”茄子快传”是联想开发的一款近距离文件共享软件。它通过wifi-direct(速度飞快,不须要联网)或者普通的网络(速度慢)在不同手机间传递文件。

不知为何。它就火了起来,火的也飞快。当中。共享传输已安装程序文件apk这一功能引起了我强烈的兴趣。

我们知道android对每一个应用的权限做了非常苛刻的控制,每一个应用程序有自己的用户id,每一个应用程序仅仅能訪问自己的数据,比方程序com.android.calculator计算器程序仅仅被同意訪问/data/data/com.android.calculator文件夹下的数据。且该程序的全部数据也都保存在该文件夹下。同一时候当程序被安装时,系统会将安装文件apk复制到/data/app文件夹下。那茄子快船作为普通的程序,它怎么具有读取/data/app下apk文件的权限的呢?假设它不是读取该文件夹下的apk文件,那程序的安装文件apk它是从哪里获取到的呢?

于是,我開始充分发挥主观能动性,開始不停思考它的实现方法。并有了例如以下想法和实践。

实现原理分析及实践


1)  实现方式一:

一開始我非常坚定的觉得茄子快船肯定不是读取手机里的程序的安装文件apk。我觉得它仅仅只是读取了系统全部已安装程序的信息,然后依据程序的包名在网络server上搜索相应的安装文件(apk文件)并下载,然后再通过网络传送给其它手机。

为了验证这一推測,我猜想仅仅要我断了网络。它自然没法做程序搜索,那么肯定就没法传送文件了。于是,我做了例如以下实验:

我断掉自己手机的全部网络(2g/wifi),然后再使用这个功能选择某一程序并选择发送给其它手机。结果发现它仍然工作。

于是我接着推測。这个apk文件非常有可能在程序安装的时候就从server下载到茄子快船程序的文件夹里了。因此在发送的时候它不再须要网络了。于是我又做了另外一个实验:

我断掉我全部的网络。然后通过adb安装某一程序,这样在安装的过程中,茄子快船肯定是没法从网络上下载相应的apk文件的。可是出人意料的是,茄子快船仍然成功传送了我刚刚安装的程序相应的安装文件。

2)  最后我不得不相信它确实是通过读取/data/app下的apk文件来传送安装程序的。

那我開始想了,难道/data/app下的文件本身确实是可读的。

我不信邪,我開始查看这些文件的权限信息。

于是我又開始了以下的实验。为了模拟一般程序的权限,我用shell用户来运行读取/data/app/下的文件以      验证普通程序是否有相关权限。

  1. itleaks@Itleaks/tmp$ adb shell
  2. 1|shell@htc:/ $ ls /data -al
  3. opendir failed, Permission denied
  4. shell@htc:/ $ ls /data/app -al
  5. opendir failed, Permission denied
  6. #没有权限
  7. 1|shell@htc:/ $

从上面能够看出一般的程序应该是没法直接读取/data/app以下的文件啊。不正确啊?仅仅好出绝招了。我接着又使用root用户来查看文件夹的详细权限:

  1. 1|shell@htc:/ $ su root
  2. root@htc:/ # ls /data -al
  3. ls /data -al
  4. drwxrwx--x system system 2014-06-19 20:40 app

到此,我最终明确了。原来/data/app文件夹对于其它用户具备-x权限。也就是说普通程序能够进入该文件夹。可是没法读取该文件夹文件中的内容,即没法查询该文件夹下有哪些文件。这也是为什么我们运行ls /data/app –al失败的原因,由于这个命令会读取文件夹文件,自然须要该文件夹对其它用户开放-r权限。在-x权限下,仅仅需该文件夹下的文件对第三方程序开发-r权限,那么程序就可通过详细文件名来读取该文件夹的相应文件。于是迫不及待的想看该文件夹下的文件权限属性。

  1. root@htc:/ # cd /data/app
  2. cd /data/app
  3. root@htc:/data/app # ls -al
  4. ls -al
  5. -rw-r--r-- system system 5784942 2014-05-18 15:22 cn.lvye.hd-1.apk
  6. -rw-r--r-- system system 16056547 2014-05-16 21:11 cn.whonow.whonow-1.apk

果然。文件夹下的apk对于其它用户有-r权限。于是我又一次模拟普通程序用户的权限開始例如以下的实验。

  1. root@htc:/data/app # exit
  2. exit
  3. #回到shell用户
  4. shell@htc:/ $ ls /data/app
  5. opendir failed, Permission denied
  6. shell@htc:/ $ cd /data/app
  7. #进入/data/app文件夹成功
  8. shell@htc:/data/app $ cd -
  9. /
  10. 1|shell@htc:/ $ ls /data/app/cn.lvye.hd-1.apk -al
  11. -rw-r--r-- system system 5784942 2014-05-18 15:22 cn.lvye.hd-1.apk
  12. #读取apk文件成功

从上面能够看出,shell用户已经成功读取到cn.lvye.hd-1.apk文件的信息。可是另一个问题,我们刚刚是通过root用户来查看/data/app文件夹下的apk文件的名字的。对于普通用户来说,它是没法知道/data/app下有哪些文件的,那它是怎样知道某一个程序的安装文件名称的呢?事实上这个非常easy。已安装程序的PackageInfo.sourceDir信息会指明该程序的安装程序名称及路径。详细获代替码例如以下:

  1. public class MainActivity extends Activity {
  2.  
  3. private static final String TAG = "Itleaks test";
  4.  
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9. readFirstApkFile();
  10. }
  11.  
  12. private void readFirstApkFile() {
  13. // TODO Auto-generated method stub
  14. List<PackageInfo> installedList = this.getPackageManager().getInstalledPackages(0);
  15. int installedListSize = installedList.size();
  16. ApplicationInfo firstApplicationInfo = null;
  17. for(int i = 0; i < installedListSize; i++) {
  18. PackageInfo info = installedList.get(i);
  19. ApplicationInfo aInfo = info.applicationInfo;
  20. Log.d(TAG, "application source dir " + aInfo.sourceDir);
  21. if (firstApplicationInfo == null) {
  22. firstApplicationInfo = aInfo;
  23. }
  24. }
  25. File file = new File(firstApplicationInfo.sourceDir);
  26. if (!file.exists()) {
  27. Log.e(TAG, "package:" + firstApplicationInfo.packageName
  28. + " Apk file " + firstApplicationInfo.sourceDir + " doesn't exist");
  29. } else {
  30. FileInputStream in = null;
  31. try {
  32. in = new FileInputStream(file);
  33. int size;
  34. try {
  35. size = in.available();
  36. Log.d(TAG, "Apk file " + firstApplicationInfo.sourceDir + " size:" + size);
  37. } catch (IOException e) {
  38. // TODO Auto-generated catch block
  39. e.printStackTrace();
  40. }
  41. } catch (FileNotFoundException e) {
  42. // TODO Auto-generated catch block
  43. e.printStackTrace();
  44. }
  45. }
  46. }
  47. }

对于乐视lvye这个程序,其sourceDir为/data/app/cn.lvye.hd-1.apk,有了这个文件路径,普通程序就能够通过一般的文件读取操作来读取该文件了。

附录:


大家能够在github上下载到文中的源代码及apk文件:

https://github.com/itleaks/apkfileshare

/********************************

* 本文来自博客  “爱踢门”

* 转载请标明出处:http://blog.csdn.net/itleaks

******************************************/

附录:


大家能够在github上下载到文中的源代码及apk文件:

https://github.com/itleaks/apkfileshare

/********************************

* 本文来自博客  “爱踢门”

* 转载请标明出处:http://blog.csdn.net/itleaks

******************************************/

从”茄子快传”看应用程序怎样获取手机已安装程序的apk文件的更多相关文章

  1. AutoIt:获取计算机已安装程序列表

    $file = FileOpen(@ScriptDir&"\RegInstalledItems.csv",1) if $file = -1 Then ConsoleWrit ...

  2. Android如何实现茄子快传

    Android如何实现茄子快传茄子快传是一款文件传输应用,相信大家都很熟悉这款应用,应该很多人用过用来文件的传输.它有两个核心的功能: 端到端的文件传输Web端的文件传输这两个核心的功能我们具体来分析 ...

  3. 技能Get·将浏览器已安装程序打包

    阅文时长 | 0.51分钟 字数统计 | 820字符 主要内容 | 1.前言&环境说明&预备知识 2.详细步骤 3.声明与参考资料 『技能Get·将浏览器已安装程序打包』 编写人 | ...

  4. 使用LabVIEW如何生成应用程序(exe)和安装程序(installer)

    主要软件:   LabVIEW Development Systems>>LabVIEW Professional Development System主要软件版本:   2012主要软件 ...

  5. 打开win8及以上操作系统的系统已安装程序目录

    Windows 8 的“Metro 界面”里不能像XP和Win7那样,点击“开始”->“程序”,显示系统所有安装的程序,这个功能还是非常有用的,可以帮助我们快速查看系统已经安装的程序!我编写了这 ...

  6. C# winform程序如何打包64位安装程序

    故事背景: 原来在客户电脑上工作的很正常的程序,在客户将其操作系统从32位换为64位之后,出现了不能正常使用的问题. --------------------------- 解决办法: 1:将解决方案 ...

  7. (Inno setup打包)检测系统是否已安装程序,若已安装则弹出卸载提示的代码

    原文 http://bbs.itiankong.com/thread-30983-1-5.html 有6天没研究pascal代码了,昨天晚上突然来了灵感,终于解决了苦思冥想好几天没能解决的问题, 因此 ...

  8. iOS 在 程序内调用手机上安装的地图软件进行导航

    // 需求是需要用户 能从 所在位置 到 附近的健身房的 路线, 然而,就一个需求,不值当的添加一个地图, 就用调用手机上第三方地图软件,  什么高德, 百度, 腾讯, iOS 原生地图都可以, 如果 ...

  9. Android-获取手机已经安装的程序

    有时候我们会查询手机里面是否安装了某个程序,或者获取已经安装软件名称的集合. android这边提供了相应的接口. [java] view plaincopy final PackageManager ...

随机推荐

  1. Linux 下安装 redis 详情

    一:将redis 压缩包上传到 Linux  usr/local下 (一):在local 下创建一个 redis 目录 (二):上传redis压缩包到此目录下. 二:Linux 进入 local目录下 ...

  2. 20180929 北京大学 人工智能实践:Tensorflow笔记08

    https://www.bilibili.com/video/av22530538/?p=28 ———————————————————————————————————————————————————— ...

  3. swift 动态设置UILabel的高度

    import UIKit class ViewController3: UIViewController {          override func viewDidLoad() {        ...

  4. linux 下的select函数

    函数原型 /* According to POSIX.1-2001 */ #include <sys/select.h>  //头文件 /* According to earlier st ...

  5. mvc下是如何传值的

    最近在开发一个项目,用的是mvc框架,现将mvc会用到的常用传值方法总结如下: 在讲传递参数方法之前,先简单介绍一下MVC路由及运行机制.     首先,Web 浏览器向服务器发送一条URL 请求,如 ...

  6. linux和Windows双系统让 Windows 把硬件时间当作 UTC

    linux和Windows双系统让 Windows 把硬件时间当作 UTC Windows设置如下:开 始->运行->CMD,打开命令行程序(Vista则要以管理员方式打开命令行程序方可有 ...

  7. 【Uva 12105】Bigger is Better

    [Link]: [Description] 让你用最多n根棍子,组成一个数字,使得它能够被m整除; 数字1..9分别需要用-根棍子. 要求这个数字尽可能地大; 然后输出这个数字. [Solution] ...

  8. python程序转exe程序之一——cx_Freeze

    原始网页 : http://keliang.blog.51cto.com/3359430/661884 本人用的64位系统,一开始装了32位的cx_freeze,结果貌似无法自动找到本地的python ...

  9. 洛谷——P2446 [SDOI2010]大陆争霸

    https://www.luogu.org/problem/show?pid=2446#sub 题目背景 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的克里斯国.两个国家的人民分别 ...

  10. CS224d lecture 9札记

    欢迎转载.转载注明出处: http://blog.csdn.net/neighborhoodguo/article/details/47193885 近期几课的内容不是非常难.还有我的理解能力有所提高 ...