【Android端APP 安裝包檢查】安裝包檢查具體內容及實現方法


一、安裝包檢查的具體包含內容有哪些?

 

1、安裝包檢查的一般內容包括:

 

安裝包基本信息檢查:

文件大小: xx MB

包名: com.xx

名稱:  xx

本次安裝包證書與外網證書對比一致性:是

版本號: xx.xx.xx

內部版本號: xx

min SDK:xx

log是否關閉:是

是否混淆: 是

重復文件個數:xx 項

重復文件大小:xx KB/MB

 

資源文件空文件列表:

 

資源文件重復文件列表:(共xx項)

 

二、獲取具體的內容的方案:

 

具體需要獲取的內容如下:

(一)關於混淆

1、什么是混淆?

混淆代碼是為了防止代碼被反編譯之后,能夠得到代碼的實現邏輯等;

Android端的代碼混淆的方案:

程序中能夠看到一個文件,是:project.properties,找到這個文件,就能找到混淆配置的文件路徑了,如:

然后這里可以看到proguard.config = proguard.cfg,然后找到這個文件,就能看到類似這樣的結構:

 

其中意義如下:

 a. 把所有你的jar包都申明進來,例如:

 -libraryjars libs/apns_1.0.6.jar

 -libraryjars libs/armeabi/libBaiduMapSDK_v2_3_1.so

 -libraryjars libs/armeabi/liblocSDK4.so

-libraryjars libs/baidumapapi_v2_3_1.jar

-libraryjars libs/core.jar

-libraryjars libs/gesture-imageview.jar

-libraryjars libs/gson-2.0.jar

-libraryjars libs/infogracesound.jar

-libraryjars libs/locSDK_4.0.jar

-libraryjars libs/ormlite-android-4.48.jar

-libraryjars libs/ormlite-core-4.48.jar

-libraryjars libs/universal-image-loader-1.9.0.jar

b. 將你不需要混淆的部分申明進來,因為有些類經過混淆會導致程序編譯不通過,如下:

-keep public class * extends android.app.Fragment  

-keep public class * extends android.app.Activity

-keep public class * extends android.app.Application

-keep public class * extends android.app.Service

-keep public class * extends android.content.BroadcastReceiver

-keep public class * extends android.content.ContentProvider

-keep public class * extends android.app.backup.BackupAgentHelper

-keep public class * extends android.preference.Preference

-keep public class * extends android.support.v4.**

-keep public class com.android.vending.licensing.ILicensingService

--以上都是API里邊的類,最好都要避免混淆

有些很特殊的,例如百度地圖,你需要添加以下申明:

-keep class com.baidu.** { *; } 

-keep class vi.com.gdi.bgl.android.**{*;}

 

2、判定代碼是否混淆的方案判定?

首先可以通過手工的方式來判定代碼是否經過了混淆,可以通過以下幾種方式:

(1)先對安裝包進行解壓,之后能夠得到classes.dex這樣的文件,然后從網上下載dex2jar的工具先將dex轉成jar,之后再使用jd-gui的exe將jar包轉成class文件:

現在dex2jar.bat可以直接后面加classes.dex的路徑就能生成到對應的文件,所以可以通過如下方式調用命令行:

 

D:\Program Files\反編譯工具\反編譯工具\dex2jar-2.0\dex2jar-2.0>d2j-dex2jar.bat C

:\Users\58\Desktop\趕集生活app包\GJAndroid_release_20161115\classes.dex C:\Users

\58\Desktop\趕集生活app包\GJAndroid_release_20161115\classes2.dex C:\Users\58\De

sktop\趕集生活app包\GJAndroid_release_20161115\classes3.dex  --force

dex2jar C:\Users\58\Desktop\趕集生活app包\GJAndroid_release_20161115\classes.dex

 -> .\classes-dex2jar.jar

dex2jar C:\Users\58\Desktop\趕集生活app包\GJAndroid_release_20161115\classes2.de

x -> .\classes2-dex2jar.jar

dex2jar C:\Users\58\Desktop\趕集生活app包\GJAndroid_release_20161115\classes3.de

x -> .\classes3-dex2jar.jar

 

其中--force的含義是:強制刪除之前的結果文件,用新的文件覆蓋老的文件

 

D:\Program Files\反編譯工具\反編譯工具\dex2jar-2.0\dex2jar-2.0>d2j-dex2jar.bat C

:\Users\58\Desktop\趕集生活app包\GJAndroid_release_20161115\classes.dex -o e:\11

1\111.jar -f

dex2jar C:\Users\58\Desktop\趕集生活app包\GJAndroid_release_20161115\classes.dex

 -> e:\111\111.jar

以上命令只能一條一條用,-o的命令行選項只能一次對應一個文件

 

如果有三個classes.dex的類似文件的話,可以循環,執行三條命令(解壓之后掃描文件即可)

————————————————————————————————————————

接下來可以通過jd-gui的工具查看jar包:

 

需要首先確定我們的APP的代碼的路徑,比如趕集是:com.ganji.android的這個路徑下面的;因為可能里面包含很多第三方的jar包本身就已經是混淆過的了。

 

(2)可以通過.smali的方式對資源文件進行判定,如果沒有經過混淆,那就需要根據LaunchActivity.smali的文件內容來確定:

針對部分APK來說,直接通過apktool來判斷R.smali之類的文件是否存在就可以判定,如果存在說明進行了混淆,如果不存在,則需要繼續搜索LaunchActivity(啟動Activity)的文件,對文件內容進行掃描。

首先,apktool通過命令行的使用方式如下:

C:\Users\58>apktool d  C:\Users\58\Desktop\趕集生活app包\all\GJAndroidClient15\ant-build\signed\GJAndroidClient15-gray-release.apk -o  E:\weihunxiao -f

主要參數如下:d 代表的是將apk文件進行decode, -o 代表的是進行output的dir, -f 指的是force,即強行覆蓋安裝

 

之后打開對應的文件夾,找到smali/com/ganji/android這個目錄,看下方圖示中的文件是否存在

如果資源文件經過了混淆的話,就不會存在這些文件,否則就會存在;以58主app為例,58主app的資源文件做了混淆,因此不存在R.smali這樣的文件:

 

所以針對58主app這類的資源文件經過了混淆的,就找不到以上提到的R.samli的文件,此種情況下可以認為已經經過資源混淆;

第二步就是:針對趕集這樣的,資源文件沒有經過混淆的,就需要繼續找LaunchActivity(啟動Activity)的文件,通過對文件內容的判定來確定是否經過了混淆。

 

如何找到LaunchActivity的文件,就需要通過aapt的命令得到啟動的Activity,然后通過這個文件路徑去找,比如趕集網的APP的launchActivity.smali的路徑如下:(備注:有可能文件比較多的情況下,會生成多個smali的文件夾,會命名為smali、smali2、smali3這樣的,如果是三個文件夾都存在,就需要對三個文件夾都進行對應的文件路徑Path拼接,之后判斷是否存在對應的文件,再做進一步的文件內容的判定)

找到這個文件之后,打開,能夠看到:

以上截圖中能看到的只是針對#instance fields的內容,文件中還包含:#direct methods的內容

具體程序實現時,需要處理的就是:

通過文件行數掃描的方式,先得到:# interfaces,# annotations,# static fields,# instance fields,# direct methods這一行,之后繼續往下掃描,如果下一行非空且不是以#開頭的,就可以先放入到一個以 interfaces、annotations等為key的value為list的列表中。

之后就可以對內容進行判定了,比如說針對instance fields的list中的內容做判斷,需要遍歷,比如說:.field private a:J,按照冒號分割之后取index為0的部分:.field private a,然后再獲取以空格分割的-1的index值的內容,判斷該值是否存在於rulelist中,其中rulelist可以先暫定從a到z的26個字母。

其他類似。

 

(二) 關於資源文件的判定:空文件和重復文件的檢測

 

首先安卓端的解壓也可以直接用unzip.exe進行,這個工具直接搜索下載即可,有windows和linux下的。

然后解壓之后可以生成到一個新的文件夾,然后針對整個新文件夾做一個資源文件的掃描。

 

命令行使用:unzip 安卓APK的路徑 -d 解壓之后的dest目錄

 

如何判定資源文件呢?不能簡單通過后綴名,需要對文件格式的文件頭進行判定:

下面是從網上查到的文件格式 文件頭(十六進制)   

JPEG (jpg) FFD8FF

PNG (png) 89504E47

GIF (gif) 47494638

TIFF (tif) 49492A00

Windows Bitmap (bmp) 424D

CAD (dwg) 41433130

Adobe Photoshop (psd) 38425053

Rich Text Format (rtf) 7B5C727466

XML (xml) 3C3F786D6C

HTML (html) 68746D6C3E

Email [thorough only] (eml) 44656C69766572792D646174653A

Outlook Express (dbx) CFAD12FEC5FD746F

Outlook (pst) 2142444E

MS Word/Excel (xls.or.doc) D0CF11E0

MS Access (mdb) 5374616E64617264204A

 

然后通過對文件進行遍歷,在遍歷的過程中判斷文件的類型,是資源文件的才走下一步的判定,如果是資源文件,則判定大小,如果大小為0,則append到emptyFileList中;如果兩個文件的大小一致,之后判斷md5值是否一致,如果是的話,則將set(file1, file2)append到sameFileList中。

 

注意:針對相同文件的判定中,因為通過循環判定,因此需要進行去重,就需要通過set的方式進行去重。

然后下面針對這個空文件的list和重復文件的list進行輸出即可。

 

(三)針對其他項的獲取:

 

先通過aapt.exe獲取——包名、名稱、版本號、內部版本號、以及Min.SDK、權限

調用方法是:aapt dump badging APK包的路徑

如下:

——>包名、內部版本號、版本號:

package: name='com.ganji.android' versionCode='470' versionName='7.7.0'

——>sdkVersion:'15'——把sdk版本與安卓的版本對應起來

——>權限的話——參照官方文檔,將英文翻譯成對應的中文權限即可

——>文件md5值:

可以通過如下方式獲得:

 1 def md5_for_file(file_path, block_size=2**20):
 2     md5 = hashlib.md5()
 3     f = open(file_path, 'rb')
 4     try:
 5         while True:
 6             data = f.read(block_size)
 7             if not data:
 8                 break
 9             md5.update(data)   
10     except Exception, e:
11         print e
12     finally:
13         f.close()
14     return md5.hexdigest()

——>證書的md5值:

通過:

(1)unzip.exe -j apk /META-INF/*.RSA -d 自定義的文件夾,就能得到證書

(2)得到證書文件之后,通過keytool -printcert -file  .RSA文件的路徑(其中keytool只要配置了java的環境變量就可以使用,參考資料可見:http://www.micmiu.com/lang/java/keytool-start-guide/)

需要跟APP正確的md5值進行比較,sha1也可以輸出,比較之后,如果一致,認為OK

例如:比如下方是轉轉APK的,直接解壓apk文件夾之后,進入到META-INF\zhuanzhuan.RSA 

命令是keytool -printcert -file RSA文件的路徑,然后就能得到證書指紋 MD5:xxx 和 SHA1:xxx

證書文件的獲得:可以先通過unzip命令將APK包的*.RSA文件先解壓生成到rr的這個文件夾下:

——>大小:os.path.getsize(APK的文件路徑)即可

 

(四)關於日志輸出的檢查:

——>日志是否關閉的判斷,可以通過兩種方式來走,如果你的app中有配置文件可以直接查看就可以獲取文件內容,如果不是,就需要通過運行程序截取文件的日志信息,然后進行判定。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM