天天看點

抛開android擷取app的簽名 —— 一次源碼探索之旅

       在android中的利用PackageManager可以很輕松得到一個app的簽名哈希值,但是需要在android下弄一次比較麻煩。其實完全可以抛開android擷取,很多軟體之類的都實作了,隻是不知道怎麼實作的。今天正好有興趣,小小的探索了一下。

       簽名哈希值是PackageManager的getPackageInfo方法擷取的,但是PackageManager是一個抽象類。。。而且找了半天也沒找到子類之類的東西,上來就卡住了。。。。

       隻好求組萬能的百度,原來有個PackageManagerService,在com\android\server\pm下,不過關于位置網上說法不一樣。PackageManagerService近萬行代碼,看的腦袋痛。還好網上有高手進行了詳細分析http://www.open-open.com/lib/view/open1328776151311.html。大概看了看,我最關心的還是簽名,直接看有關簽名的部分。

抛開android擷取app的簽名 —— 一次源碼探索之旅

      可以看的是在collectCertificatesLI這個方法裡,這裡調用android\content\pm\PackageParser的CollectCertificates方法,在這個方法裡就可以看的通過JarFile來解析apk包,周遊裡面的JarEntry,再調用JarEntry的getCertificates()來擷取簽名。這裡就可以将代碼簡單修改一下脫離android直接用JarFile來解析apk包擷取簽名。

      其實呢,JarEntry的getCertificates()實質上是得到apk包裡的簽名檔案CERT.RAS解析出簽名的,也可以直接把這個檔案拿出來,用更簡單的方法解析擷取簽名,不過感覺沒什麼必要,而且好像不僅僅需要這一個檔案就夠了。

      整個過程很簡單,隻是在PackageManagerService上花了一些時間,但還是沒太看明白,看了那個高人寫的也比較茫然,看來隻能等以後再研究了。後來又接着向下研究簽名,發現簽名檔案所關聯的JarEntry每個apk包都不同,研究很久沒發現那個JarEntry有什麼特别的代碼,而且有關的源碼是不全的。。。

      這樣的話就可以寫一個小工具了,十幾行代碼就可以了,可以很輕松的擷取一個apk包的簽名哈希值,其實也可以獲得簽名的具體内容。