標籤:讀取程式安裝檔案 android 讀取apk檔案
”茄子快傳”是聯想開發的一款近距離檔案分享權限設定軟體,它通過wifi-direct(速度飛快,不需要連網)或者普通的網路(速度慢)在不同手機間傳遞檔案。不知為何,它就火了起來,火的也飛快。其中,共用傳輸已安裝程式檔案apk這一功能引起了我強烈的興趣。
我們知道android對每個應用的許可權做了很苛刻的控制,每個應用程式有自己的使用者id,每個應用程式只能訪問自己的資料,比如程式com.android.calculator計算機程式只被允許訪問/data/data/com.android.calculator目錄下的資料,且該程式的所有資料也都儲存在該目錄下。同時當程式被安裝時,系統會將安裝檔案apk拷貝到/data/app目錄下。那茄子快船作為普通的程式,它怎麼具有讀取/data/app下apk檔案的許可權的呢?如果它不是讀取該目錄下的apk檔案,那程式的安裝檔案apk它是從哪裡擷取到的呢?
於是,我開始充分發揮主觀能動性,開始不停思考它的實現方法,並有了如下想法和實踐。
實現原理分析及實踐
1) 實現方式一:
一開始我很堅定的認為茄子快船肯定不是讀取手機裡的程式的安裝檔案apk。我認為它只不過讀取了系統所有已安裝程式的資訊,然後根據程式的包名在網路伺服器上搜尋對應的安裝檔案(apk檔案)並下載,然後再通過網路傳送給其他手機。
為了驗證這一猜測,我猜想只要我斷了網路,它自然沒法做程式搜尋,那麼肯定就沒法傳送檔案了。於是,我做了如下實驗:
我斷掉自己手機的所有網路(2g/wifi),然後再使用這個功能選擇某一程式並選擇發送給其他手機,結果發現它仍然工作。
於是我接著猜測,這個apk檔案很有可能在程式安裝的時候就從伺服器下載到茄子快船程式的目錄裡了,因此在發送的時候它不再需要網路了。於是我又做了另外一個實驗:
我斷掉我所有的網路,然後通過adb安裝某一程式,這樣在安裝的過程中,茄子快船肯定是沒法從網路上下載相應的apk檔案的。但是出人意料的是,茄子快船仍然成功傳送了我剛剛安裝的程式對應的安裝檔案。
2) 最後我不得不相信它確實是通過讀取/data/app下的apk檔案來傳送安裝程式的。
那我開始想了,難道/data/app下的檔案本身確實是可讀的。我不信邪,我開始查看這些檔案的許可權資訊。 於是我又開始了下面的實驗。為了類比一般程式的許可權,我用shell使用者來執行讀取/data/app/下的檔案以 驗證普通程式是否有相關許可權。
[email protected]/tmp$ adb shell1|[email protected]:/ $ ls /data -al opendir failed, Permission denied[email protected]:/ $ ls /data/app -alopendir failed, Permission denied#沒有許可權1|[email protected]:/ $
從上面可以看出一般的程式應該是沒法直接讀取/data/app下面的檔案啊,不對啊?只好出絕招了,我接著又使用root使用者來查看目錄的具體許可權:
1|[email protected]:/ $ su root[email protected]:/ # ls /data -alls /data -aldrwxrwx--x system system 2014-06-19 20:40 app
到此,我終於明白了,原來/data/app目錄對於其他使用者具備-x許可權。也就是說普通程式可以進入該目錄,但是沒法讀取該目錄檔案裡的內容,即沒法查詢該目錄下有哪些檔案。這也是為什麼我們執行ls /data/app –al失敗的原因,因為這個命令會讀取目錄檔案,自然需要該目錄對其他使用者開放-r許可權。在-x許可權下,只需該目錄下的檔案對第三方程式開發-r許可權,那麼程式就可通過具體檔案名稱來讀取該目錄的對應檔案。於是迫不及待的想看該目錄下的檔案許可權屬性。
[email protected]:/ # cd /data/appcd /data/app[email protected]:/data/app # ls -alls -al-rw-r--r-- system system 5784942 2014-05-18 15:22 cn.lvye.hd-1.apk-rw-r--r-- system system 16056547 2014-05-16 21:11 cn.whonow.whonow-1.apk
果然,目錄下的apk對於其他使用者有-r許可權。於是我重新類比普通程式使用者的許可權開始如下的實驗。
[email protected]:/data/app # exitexit#回到shell使用者[email protected]:/ $ ls /data/appopendir failed, Permission denied[email protected]:/ $ cd /data/app#進入/data/app目錄成功[email protected]:/data/app $ cd -/1|[email protected]:/ $ ls /data/app/cn.lvye.hd-1.apk -al-rw-r--r-- system system 5784942 2014-05-18 15:22 cn.lvye.hd-1.apk#讀取apk檔案成功
從上面可以看出,shell使用者已經成功讀取到cn.lvye.hd-1.apk檔案的資訊。但是還有一個問題,我們剛剛是通過root使用者來查看/data/app目錄下的apk檔案的名字的,對於普通使用者來說,它是沒法知道/data/app下有哪些檔案的,那它是如何知道某一個程式的安裝檔案名稱的呢?其實這個很簡單,已安裝程式的PackageInfo.sourceDir資訊會指明該程式的安裝程式名稱及路徑。具體擷取代碼如下:
public class MainActivity extends Activity {private static final String TAG = "Itleaks test";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);readFirstApkFile();}private void readFirstApkFile() {// TODO Auto-generated method stub List<PackageInfo> installedList = this.getPackageManager().getInstalledPackages(0); int installedListSize = installedList.size(); ApplicationInfo firstApplicationInfo = null; for(int i = 0; i < installedListSize; i++) { PackageInfo info = installedList.get(i); ApplicationInfo aInfo = info.applicationInfo; Log.d(TAG, "application source dir " + aInfo.sourceDir); if (firstApplicationInfo == null) { firstApplicationInfo = aInfo; } } File file = new File(firstApplicationInfo.sourceDir); if (!file.exists()) { Log.e(TAG, "package:" + firstApplicationInfo.packageName + " Apk file " + firstApplicationInfo.sourceDir + " doesn't exist"); } else { FileInputStream in = null;try {in = new FileInputStream(file);int size;try {size = in.available(); Log.d(TAG, "Apk file " + firstApplicationInfo.sourceDir + " size:" + size);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} }}}
對於樂視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
******************************************/