前言
反編譯別人的程式不是什麼值得炫耀的事,希望大家最好只是興趣探索,而不是利益驅動。本文主要目的是繞開一個簡單的啟用程式。
什麼是反編譯
我們知道,Android的程式打包後會生成一個APK檔案,這個檔案可以直接安裝到任何Android手機上,因此,反編譯就是對這個APK進行反編譯。Android的反編譯分成兩個部分:
- 一個是對程式碼反編譯,也就是java檔案的反編譯。
- 一個是對資源反編譯,也就是res檔案的反編譯。
所需的工具
- Android Studio:安卓開發IDE下載地址:https://developer.android.com/studio/index.html
反編譯程式碼的工具:
- dex2jar: 把dex檔案轉成jar檔案下載地址:https://sourceforge.net/projects/dex2jar/files/
- jd-gui: 這個工具用於將jar檔案轉換成java程式碼下載地址:http://jd.benow.ca/
反編譯資源的工具:
- APKTool: 本文重要工具,APK逆向工具,使用簡單下載地址: http://ibotpeaches.github.io/Apktool/install/
熱身準備
首先我們需要一個APK,這裡我自己寫了一個,原始碼下載地址:http://download.csdn.net/detail/u012891055/9563180,打包成APK後下載到手機上。
它的主要功能是模擬郵箱啟用,如果我們輸入了錯誤的資料則無法通過啟用。所以我們的目的很簡單,就是讓這個判斷邏輯失效。
主要原始碼說明:
第51行
儲存的正確的兩個啟用號碼,通過:
將賬號密碼隔開,如下
1 2 3 4 |
private static final String[] DUMMY_CREDENTIALS = new String[]{ "foo@163.com:20135115", "bar@163.com:20135115" }; |
現在只有啟用碼正確才能通過啟用。
第331行
是Execute函式,邏輯判斷的部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Override protected void onPostExecute(final Boolean success) { mAuthTask = null; showProgress(false); if (success) { new AlertDialog.Builder(LoginActivity.this) .setTitle("恭喜您") .setMessage("成功啟用!") .show(); // finish(); } else { mPasswordView.setError(getString(R.string.error_incorrect_password)); mPasswordView.requestFocus(); } } |
反編譯程式碼
dex2jar解壓下來檔案很多,在mac上我們需要用到dex2jar的是這三個東西(windows上對應用bat檔案):
- d2j_invoke.sh
- d2j-dex2jar.sh
- lib
AndroidStudio
打包好的APK檔案
的字尾,需改為.zip
,然後解壓
。從解壓的檔案中找到classes.dex檔案,並將其放入dex2jar同一目錄下,如下:
並在cmd中也進入到同樣的目錄,然後執行:
1 |
sh d2j-dex2jar.sh classes.dex |
執行如下:
然後我們會得到一個classes-dex2jar.jar檔案,我們藉助JD-GUI工具開啟即可,開啟如下:
可以看到程式碼非常清晰,這樣我們就可以看到整個APP的程式碼邏輯了。
反編譯資源
apktool下載完成後有一個.sh檔案和.jar檔案,我們把APK放進來,如下:
在cmd中進入apktool目錄,執行命令:
1 |
sh apktool.sh apktool d FooApp.apk |
d是decode的意思,表示我們要對FooApp解碼,結果如下:
然後你會驚喜的發現多了一個FooApp資料夾。
主要目錄說明:
- AndroidManifest.xml:描述檔案
- res:資原始檔
- smail:反編譯出來的所有程式碼,語法與java不同,類似彙編,是Android虛擬機器所使用的暫存器語言
修改App icon
開啟我們的描述檔案,高清無碼:
可以看到我們的App icon名稱為ic_launcher,我們找到所有mipmap開頭的資料夾,替換成下圖即可:
在最後重新打包後我們的App icon就會被修改了,不過在重新打包之前,我們還有最重要的一件事沒有做,那就是修改啟用碼判斷邏輯。
修改邏輯
我們通過原始碼或者JD-GUI檢視反編譯的程式碼可以看到啟用碼判斷邏輯如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Override protected void onPostExecute(final Boolean success) { mAuthTask = null; showProgress(false); if (success) { // 啟用碼正確 new AlertDialog.Builder(LoginActivity.this) .setTitle("恭喜您") .setMessage("成功啟用!") .show(); // finish(); } else { mPasswordView.setError(getString(R.string.error_incorrect_password)); mPasswordView.requestFocus(); } } |
所以我們只需要找到反編譯後的if(success)
的語句,並將其修改成if(!success)
即可,如下:
1 2 3 4 5 6 |
if (success)//修改成if(!success) { ... } else { ... } |
這樣我們就成功的顛倒了以前的邏輯,我們輸入一個錯誤的啟用碼,就會被判斷成正確的。挺簡單的,是吧。
現在我們來動手修改:
- 開啟smail裡的
LoginActivity$UserLoginTask.smali
檔案. - 全域性搜尋
if-eqz
,通過AlertDialog
關鍵字輔助定位,發現在第228行
: - ok,就是這裡了,然後將
if-eqz
修改成if-nez
,他們對應Java
的語法如下:
Smail 語法 | Java 語法 |
---|---|
if-eqz v0, | if(v0 == 0) |
if-nez v0, | if(v0 != 0) |
ok,大功告成,現在就可以重新打包了。關於smail語法,有興趣的直接Google就行了。
重新打包
我們大概修改後兩個地方,其實重新打包也十分簡單,在cmd中執行以下命令即可:
1 |
sh apktool.sh b FooAPP -o NewFooApp.apk |
其中b是build的意思,表示我們要將FooAPP資料夾打包成APK檔案,-o用於指定新生成的APK檔名,這裡新的檔案叫作NewFooApp.apk。執行結果如下圖所示:
然後你會發現同級目錄下生成了新的apk檔案:
但是要注意,這個apk現在還是不能安裝的,因為我們沒有對它進行簽名,重新簽名後它就是個名副其實的盜版軟體了,大家一定要強烈譴責這種行為。
重新簽名
重新簽名也是很簡單的,我直接用的一個已有簽名檔案,使用Android Studio或者Eclipse都可以非常簡單地生成一個簽名檔案。
在cmd中執行格式如下:
1 |
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore 簽名檔名 -storepass 簽名密碼 待簽名的APK檔名 簽名的別名 |
然後我們就可以用這個apk進行安裝了,為了追求更快的執行速度,我們可以對其進行一次位元組對齊,這裡就不說了。
使用盜版APK
我們用NewFooApp.apk
安裝好盜版app後,發現圖示變成了籃球,並且隨便輸入資料都能通過啟用了:
怎麼樣?總的來說還是挺有意思的吧,不過別用歪了。
參考連結:
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式