本文同步自wing的地方酒館
2018年過去了,好像今年沒寫什麼文章,主要是過了寫文章的年紀,不過有遇到奇聞軼事或者好玩的,還是會記錄下來給大家,一起樂呵樂呵。
跟Iphone X沒有太大的緣分,再螢幕又掛了之後,果斷搞了一臺邁凱倫定製版Android機,正當嗨時,發現使用豌豆莢安裝應用完畢的時候,會彈出推薦相關應用的廣告,如下圖:
在厭煩的背後,也讓我有了好奇心,這是怎麼做到的? 為什麼安裝完成的介面會有廣告? 為此我將從豌豆莢下載安裝的app和正常安裝的app進行了對比。
正常安裝
豌豆莢安裝
觀察
通過觀察 我們發現,居然安裝完畢之後,居然不是同一個Activity,為此,我開啟了我的DroidSword外掛,來觀察安裝完畢的Activity到底是何方神聖。
從DroidSword中我們可以看出,安裝完畢以後並非系統Activity:
而是 com.pp.assistant.install.installfinish.InstallFinishActivity.
(PP跟豌豆莢合併了?)
什..什麼?? 為甚安裝完畢的Activity是他自己的Activity,那系統的Activity去哪了?被幹掉了嗎?Android真的不安全,假想一下,如果其他App掌握了這個技術,我在一個商城下載了美團,直接彈出餓了麼,那是多麼可怕的一件事情。
好吧,這不是我們今天的重點,我們今天的重點是,豌豆莢是如何把系統的安裝介面給幹掉了。
破案
於是我就開始沉思,猜測這是怎麼實現的。通常的做法是做一個Recevier ,監聽完畢,然後關閉掉系統安裝完成的Activity,彈出我自己的Activity,可是我如何關閉Activity呢。我為了安全起見,並沒有root和給豌豆莢授權輔助功能,所以豌豆莢並沒有辦法幫我關掉Activity。那這到底是什麼黑科技呢?
於是我開啟了debug之路,開啟DroidSword ,並且開啟“除錯所有應用”功能,就可以debug任意一個App了,這個功能要感謝XInstaller,因為實在太好用了,為了方便,我就移植到了DroidSwrod中。
除錯之路漫漫,從InstallFinishActivity 除錯到 startActivity的入口,糾結了很久,都沒有發現是如何kill掉系統安裝完畢的Activity的。
可以拿到的情報就只有註冊了一個StaticPackageReceiver,在這個Receiver裡面,做了對新安裝應用的監聽,以及包名的判斷,最終判斷是否豌豆莢推薦來的來啟動InstallFinishActivity。
這裡有個疑問先賣一下關子,為什麼豌豆莢要判斷是否豌豆莢安裝的應用才啟動他的Activity,如果有黑科技,那麼全程所有安裝都替換掉,賣廣告豈不是美滋滋?
之後開始懷疑,是否是自己實現了一個安裝檔案的Activity,可是又好像自己實現的話,並沒有許可權可以這樣做。 然後觀察豌豆莢的轉跳安裝頁面,也確實只是系統的
com.android.packageinstaller.PackageInstallerActivity
複製程式碼
那也就是說沒有自己實現一個安裝時候的Activity。而且DroidSword也看不到在從豌豆莢轉跳到安裝介面的時候,有另外一個Activity彈出。
哎,愁啊,發愁啊,他到底怎麼實現的呢,在我毫無頭緒的時候,突然一個意外點選事件,提示了我:
WTF
這什麼鬼,說好的豌豆莢自己沒有實現一個安裝程式呢? 難道是DroidSword 有問題了?他顯示的完全就是系統的安裝器啊! 於是我點選了下去,選擇了豌豆莢的安裝器。然後我發現。。。。
豌豆莢居然顯示 安全安裝(推薦),加粗 ,必須加粗!!
打廣告也就算了,還把我係統安裝器hook掉了,hook掉也就算了,你居然誤導使用者以系統的身份來開啟你的安裝器,去接受你推薦的廣告。。 真是不敢想象如果一個小白使用者,不小心點選了始終,每次安裝都會強行,被迫接受來自豌豆莢的廣告。這也有點太【文化人】了。
吐槽完畢,然後我開啟了豌豆莢的安裝器,發現 。。臥槽!!!!轉跳的還是系統的com.android.packageinstaller.PackageInstallerActivity,並且沒有被DroidSwrod抓下來,什麼Gay ,我現在一臉黑人問號,就像這樣:
好吧,不知道做了什麼么蛾子,只能全域性搜尋安裝apk時候使用的URI了。結果果然發現一個問題:
在豌豆莢的清單檔案中,發現了一個Activity,他接受了與系統安裝器同樣的URI:
那結果很明確了,肯定是用這個Activity作為跳板,然後轉跳到系統Activity了。那為什麼DroidSword會跟蹤不到呢?於是我開啟了這個Activity。。然後發現了。。
他並沒有setContentView,而是給自身windowmanager加了個new view(),layoutParams 寬和高設定的大小是v4,而v4是。。
v4是 -2, -2好像是
public static final int WRAP_CONTENT = -2;
複製程式碼
也就是說,這個Activity 根本! 沒有! 大小!! 簡直比1dp Activity還可怕。 那他做了什麼事情呢,是如何幹掉系統的安裝成功頁面的呢?繼續跟蹤呼叫棧最後肯定是轉跳到系統安裝的Activity。只不過在之前,對intent做了包裝處理:
在apk版本為:Wandoujia_484050_web_seo_baidu_homepage.apk的混淆下,有一個類叫做:
.class public final Lcom/pp/installhook/e;
複製程式碼
這個類就是從豌豆莢安裝中轉Activity轉跳來的,他對intent做了個加工:
他把普通跳轉系統安裝Activity的Intent增加了一個Extra ,key為:android.intent.extra.RETURN_RESULT,值為true。 不知道這個會有啥效果,於是我寫了個Demo,執行一下,發現~!!! 安裝完成的介面居然沒有了。。 也就是說,系統安裝完成的Activity 是可以通過這個extra給幹掉的。
結果
最終總結一下豌豆莢是怎麼實現的,就是先起了一個監聽器,安裝完畢會判斷包名來決定啟動不啟動他自己的廣告頁面,現在也可以解開疑問了,為什麼要判斷呢,不判斷豈不是更好? 原因就在於,再外調起的安裝Activity一般是不帶android.intent.extra.RETURN_RESULT引數的,所以都會調起系統自身的安裝完成頁面。 如果豌豆莢不判斷包名,那麼會同時彈起系統的和他自己的廣告頁,這時候就東窗事發,做的事情大白於臺下,會影響口碑。
我按照豌豆莢的實現,自己寫了個Demo,結果如下,效果一毛一樣。
試想一下,如果這個頁面不是廣告頁,而我把安裝美團成功後的頁面調起為餓了麼頁面(這裡只是舉例,與美團餓了麼無關),無論對使用者還是企業,都是一種巨大的傷害。
反思
我沒有root也沒有給輔助功能許可權,就可以有這麼大的本領,來把系統狸貓換太子。 那實在是不敢想,如果我有root許可權呢? 恰好是小白使用者選擇了預設通過授權呢? 這些擁有root許可權的App會做什麼事情? 細思極恐。作為Android使用者,我們如何才能保護好自己?
歡迎加入Android開發 QQ群:425983695