android 手機 apk 的反編譯
阿新 • • 發佈:2019-02-12
標 題: 【原創】安卓手機下xx.apk JAVA破解之旅
作 者: zpsemo
時 間: 2012-10-04,11:17:51
鏈 接: http://bbs.pediy.com/showthread.php?t=156786
前言:這幾天手機上裝了個軟體,用了沒多久就收費了,頗為不爽,於是便想看看能否破解,便有了下文,請注意該文章只為技術交流,請不要進行非法破解。
軟體描述:這個apk使用一定次數後就會扣掉積分 當積分少於0的時候 便不能使用,每次啟動程式的時候便會提示積分為0,需要註冊,這說明程式在啟動的時候就已經檢測了積分,剛好可以利用這點
練手軟體:
http://pan.baidu.com/share/link?shareid=64695&uk=201738998
1.環境配置 首先請下載好最新的jdk,網路上到處都是,記得配置環境變數,網路都有 其次下載工具(請注意使用的時候所有路徑要是英文的)
以及簽名工具:Auto-sign_aW.zip.
2.開始反編譯
(1)使用工具apktool1.4. 他在上面提供的工具的lib目錄下,用前先將apk檔案拷本到這個目錄下,使用方法是,啟動cmd,定位到該目錄,然後鍵入命令:xxx.apk為你的apk
程式碼:
(2)開啟Gapktool.bat,選擇你的apk,及其反編譯輸出的路徑,注意不要中文,請將兩個勾選上,點選開始反編譯就會生成反編譯檔案,過不了多久就會提示儲存,以及自動開啟java decompiler
(3)需要注意到是java decompiler裡面的原始碼似乎被混淆了,很多變數或者函式詞不達意,需要自己去猜
(4)在自己設定的輸出目錄中,除了包含反編譯的程式碼外,還有其他資源,圖片等,這裡可以手動DIY或者漢化如在res\values下 包含strings.xml 這個檔案包含軟體選單的檔案,可以漢化res\values下 的drawable包含圖片資源 可以替換等等 大家可以自己發覺
3.程式碼的定位
我們的目的是為了破解,那麼程式碼的檔案在smali資料夾下,通過分析可以知道,com資料夾是程式主要的程式碼,net主要包括廣告程式碼,android應該是安卓系統的庫程式碼吧,在com資料夾加內包括許多smail的檔案這些都是主程式的核心程式碼,但是命名都沒有規則,你不知道他們是拿來幹什麼的
所幸的是 部分檔案還是可以猜出來的 ,比如activity_register.smali,An_QimenActivity.smali這些一看就知道是與註冊相關的檔案
(1)既然如此,我們就在Java Decompiler中檢視下activity_register.java,程式碼很明顯:
程式碼:
(2)我們開啟activity_register.smali 觀察程式碼:拉到最後,程式碼比較長 我們不關心別的
程式碼:
程式碼:
(2)那麼既然這個檔案沒用 我們就看另一個An_QimenActivity.java這個檔案,通過搜尋“積分”我們可以看到這樣的程式碼:
程式碼:
程式碼:
程式碼:
程式碼:
4.apk的打包和簽名
(1)同樣使用apktool1.4,命令格式為:
程式碼:
(2)開啟簽名工具auto-sign,將剛才生成的apk檔案拷貝到這裡,並且其改名為update.zip,然後執行sign.bat批處理,會自動生成一個update_signed.zip檔案,這個檔案就是簽名後的檔案,可以修改為xx.apk進行安裝了
如圖 這樣的破解後的樣子,每次點選起局都會固定返回5積分,至於你問我為什麼不修改多點積分,我也想,每次修改為其他值就編譯報錯,估計是設計到安卓程式設計的設計,或者暫存器吧這個還有待研究...............另外提供的練手壓縮包內的註冊部分 我就沒該了 留給大家練手吧,把積分搞定了等於免費了,其實還可以搞其他的,如去廣告,修改資源等等
破解到這裡就基本完成了,可以看到手機軟體寫的比較簡單,我們修改一個return就ok了,隨著安卓平臺的普及,相信未來安卓平臺的趨勢將會愈發重要
作 者: zpsemo
時 間: 2012-10-04,11:17:51
鏈 接: http://bbs.pediy.com/showthread.php?t=156786
前言:這幾天手機上裝了個軟體,用了沒多久就收費了,頗為不爽,於是便想看看能否破解,便有了下文,請注意該文章只為技術交流,請不要進行非法破解。
軟體描述:這個apk使用一定次數後就會扣掉積分 當積分少於0的時候 便不能使用,每次啟動程式的時候便會提示積分為0,需要註冊,這說明程式在啟動的時候就已經檢測了積分,剛好可以利用這點
練手軟體:
http://pan.baidu.com/share/link?shareid=64695&uk=201738998
1.環境配置 首先請下載好最新的jdk,網路上到處都是,記得配置環境變數,網路都有 其次下載工具(請注意使用的時候所有路徑要是英文的)
以及簽名工具:Auto-sign_aW.zip.
2.開始反編譯
(1)使用工具apktool1.4. 他在上面提供的工具的lib目錄下,用前先將apk檔案拷本到這個目錄下,使用方法是,啟動cmd,定位到該目錄,然後鍵入命令:xxx.apk為你的apk
程式碼:
apktool d xxx.apk然後就會在該目錄下生成反編譯的檔案,包括資源,原始碼(是java的反編譯檔案),我們將在這裡修改原始碼
(2)開啟Gapktool.bat,選擇你的apk,及其反編譯輸出的路徑,注意不要中文,請將兩個勾選上,點選開始反編譯就會生成反編譯檔案,過不了多久就會提示儲存,以及自動開啟java decompiler
(3)需要注意到是java decompiler裡面的原始碼似乎被混淆了,很多變數或者函式詞不達意,需要自己去猜
(4)在自己設定的輸出目錄中,除了包含反編譯的程式碼外,還有其他資源,圖片等,這裡可以手動DIY或者漢化如在res\values下 包含strings.xml 這個檔案包含軟體選單的檔案,可以漢化res\values下 的drawable包含圖片資源 可以替換等等 大家可以自己發覺
3.程式碼的定位
我們的目的是為了破解,那麼程式碼的檔案在smali資料夾下,通過分析可以知道,com資料夾是程式主要的程式碼,net主要包括廣告程式碼,android應該是安卓系統的庫程式碼吧,在com資料夾加內包括許多smail的檔案這些都是主程式的核心程式碼,但是命名都沒有規則,你不知道他們是拿來幹什麼的
所幸的是 部分檔案還是可以猜出來的 ,比如activity_register.smali,An_QimenActivity.smali這些一看就知道是與註冊相關的檔案
(1)既然如此,我們就在Java Decompiler中檢視下activity_register.java,程式碼很明顯:
程式碼:
package com.nfbazi.qimen; import android.app.Activity; import android.content.SharedPreferences; import android.os.Bundle; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.nfbazi.qimen.a.a; public class activity_register extends Activity { a a = new a(this); private SharedPreferences b; protected void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); setContentView(2130903043); EditText localEditText1 = (EditText)findViewById(2131165228); EditText localEditText2 = (EditText)findViewById(2131165230); localEditText1.setText(a.o); localEditText2.setFocusable(true); localEditText2.setFocusableInTouchMode(true); Button localButton1 = (Button)findViewById(2131165232); Button localButton2 = (Button)findViewById(2131165233); localButton1.setOnClickListener(new bp(this)); localButton2.setOnClickListener(new bo(this)); TextView localTextView = (TextView)findViewById(2131165231); if (a.q) //如果物件a.q欄位不為0 { localTextView.setTextColor(-16776961); //那麼設定文字顏色 localTextView.setText("您已經註冊了本程式。"); //設定文字 localEditText2.setText("************"); //設定文字 localEditText2.setEnabled(false); // 將填寫註冊碼的文字框變灰 因為已經註冊了 } } }那麼我們只要簡單的 把if(a.q)去掉就不就可以了?
(2)我們開啟activity_register.smali 觀察程式碼:拉到最後,程式碼比較長 我們不關心別的
程式碼:
.class public Lcom/nfbazi/qimen/activity_register; .super Landroid/app/Activity; # instance fields .field a:Lcom/nfbazi/qimen/a/a; .field private b:Landroid/content/SharedPreferences; # direct methods .method public constructor <init>()V .locals 1 invoke-direct {p0}, Landroid/app/Activity;-><init>()V new-instance v0, Lcom/nfbazi/qimen/a/a; invoke-direct {v0, p0}, Lcom/nfbazi/qimen/a/a;-><init>(Landroid/content/Context;)V iput-object v0, p0, Lcom/nfbazi/qimen/activity_register;->a:Lcom/nfbazi/qimen/a/a; return-void .end method .method static synthetic a(Lcom/nfbazi/qimen/activity_register;)Landroid/content/SharedPreferences; .locals 1 iget-object v0, p0, Lcom/nfbazi/qimen/activity_register;->b:Landroid/content/SharedPreferences; return-object v0 .end method .method static synthetic a(Lcom/nfbazi/qimen/activity_register;Landroid/content/SharedPreferences;)V .locals 0 iput-object p1, p0, Lcom/nfbazi/qimen/activity_register;->b:Landroid/content/SharedPreferences; return-void .end method # virtual methods .method protected onCreate(Landroid/os/Bundle;)V .locals 4 const/4 v3, 0x1 invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V const v0, 0x7f030003 invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->setContentView(I)V const v0, 0x7f07002c invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Landroid/widget/EditText; const v1, 0x7f07002e invoke-virtual {p0, v1}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View; move-result-object v1 check-cast v1, Landroid/widget/EditText; sget-object v2, Lcom/nfbazi/qimen/a/a;->o:Ljava/lang/String; invoke-virtual {v0, v2}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V invoke-virtual {v1, v3}, Landroid/widget/EditText;->setFocusable(Z)V invoke-virtual {v1, v3}, Landroid/widget/EditText;->setFocusableInTouchMode(Z)V const v0, 0x7f070030 invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Landroid/widget/Button; const v2, 0x7f070031 invoke-virtual {p0, v2}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View; move-result-object v2 check-cast v2, Landroid/widget/Button; new-instance v3, Lcom/nfbazi/qimen/bp; invoke-direct {v3, p0}, Lcom/nfbazi/qimen/bp;-><init>(Lcom/nfbazi/qimen/activity_register;)V invoke-virtual {v0, v3}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V new-instance v0, Lcom/nfbazi/qimen/bo; invoke-direct {v0, p0}, Lcom/nfbazi/qimen/bo;-><init>(Lcom/nfbazi/qimen/activity_register;)V invoke-virtual {v2, v0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V const v0, 0x7f07002f invoke-virtual {p0, v0}, Lcom/nfbazi/qimen/activity_register;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Landroid/widget/TextView; sget-boolean v2, Lcom/nfbazi/qimen/a/a;->q:Z if-eqz v2, :cond_0 //這裡的if-eqz 就是說 如果v2變數等於0的平方那麼就跳...,我們將他刪除掉 const v2, -0xffff01 //定義常量v2 invoke-virtual {v0, v2}, Landroid/widget/TextView;->setTextColor(I)V //呼叫方法設定顏色,引數為v0和v2,那麼v2應該是顏色資訊 const-string v2, "\u60a8\u5df2\u7ecf\u6ce8\u518c\u4e86\u672c\u7a0b\u5e8f\u3002" //定義字串也就是該程式已經註冊 invoke-virtual {v0, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V const-string v0, "************" //將文字框設定為********** 之後再設定為灰色 invoke-virtual {v1, v0}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V const/4 v0, 0x0 invoke-virtual {v1, v0}, Landroid/widget/EditText;->setEnabled(Z)V :cond_0 return-void [/color].end method所以完整的程式碼是:
程式碼:
上面部分一樣 從這裡開始 const v2, -0xffff01 invoke-virtual {v0, v2}, Landroid/widget/TextView;->setTextColor(I)V const-string v2, "\u60a8\u5df2\u7ecf\u6ce8\u518c\u4e86\u672c\u7a0b\u5e8f\u3002" invoke-virtual {v0, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V const-string v0, "************" invoke-virtual {v1, v0}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V const/4 v0, 0x0 invoke-virtual {v1, v0}, Landroid/widget/EditText;->setEnabled(Z)V :cond_0 return-void .end method事實上 經過以上修改之後,只是在註冊視窗上顯示註冊了 而積分依舊是0 程式碼還需要定位 這裡只是為了好看 如圖:
(2)那麼既然這個檔案沒用 我們就看另一個An_QimenActivity.java這個檔案,通過搜尋“積分”我們可以看到這樣的程式碼:
程式碼:
public String d() { com.nfbazi.qimen.a.a.a = c(); if (com.nfbazi.qimen.a.a.a < 5); for (String str = "剩餘積分:" + Integer.toString(com.nfbazi.qimen.a.a.a) + " 分。 您的積分不足。" + 10 + "次試用期過後,如果沒有註冊,還想繼續免費使用軟體,可點選程式主頁面右下角的“獲取積分”," + "通過下載安裝應用,免費獲取一定積分。" + "您也可以付費註冊本軟體,無需通過積分方式使用。點選程式主頁面左下角“選單”裡的幫助,檢視如何註冊。" + "註冊後,不會再有積分事項顯示。"; ; str = "剩餘積分:" + Integer.toString(com.nfbazi.qimen.a.a.a) + " 分。 每次點選“時家奇門”會“日家奇門”,會消費積分 " + 5 + " 分。") return str; }明顯是註冊的....通過判斷物件a.a.a是否小於5,也就是積分是否小於5來進行提示,那麼a.a.a的值使通過他上面的c()方法來得到的,我們現在在這個檔案中搜索c()程式碼;
程式碼:
public int c() { try { int i2 = YoumiPointsManager.queryPoints(this); i1 = i2; return i1; //返回的i1就是我們的積分,而i1是通過呼叫YoumiPointsManager.queryPoints(this)得到的,我們沒必要深究這個方法的實現,只要修改返回的值就得到積分了 } catch (Exception localException) { while (true) int i1 = 0; } }我們那麼開啟An_QimenActivity.smali定位到c()方法(方法名是一樣的,只是彙編程式碼不一樣) 程式碼如下:
程式碼:
.method public c()I .locals 1 :try_start_0 //異常程式碼 //得到積分 invoke-static {p0}, Lnet/youmi/android/appoffers/YoumiPointsManager;->queryPoints(Landroid/content/Context;)I :try_end_0 //異常結束 .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0 move-result v0 //將積分賦給v0返回,,我們可以在這行程式碼上面修改v0的值 這樣不管他返回多少 都會被我們覆蓋 我們可以這樣修改const/4 v3,0xxxx xxx為你需要的積分 :goto_0 return v0 :catch_0 //處理異常部分 move-exception v0 const/4 v0, 0x0 goto :goto_0 .end method修改後的程式碼是:其他都一樣 這裡只顯示c()
程式碼:
.method public c()I .locals 1 :try_start_0 invoke-static {p0}, Lnet/youmi/android/appoffers/YoumiPointsManager;->queryPoints(Landroid/content/Context;)I :try_end_0 .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0 const/4 v0,0x5 move-result v0 :goto_0 return v0 :catch_0 move-exception v0 const/4 v0, 0x0 goto :goto_0 .end method這樣我們就破解完成了.....
4.apk的打包和簽名
(1)同樣使用apktool1.4,命令格式為:
程式碼:
apktool b xxxx其中xxx為你的資料夾,如果環境配置沒錯,程式碼修改的也沒錯,那麼將順利編譯,編譯成功的檔案在你的apk目錄下的dist資料夾,將他拷貝出來,這時候還不能安裝,因為沒有簽名
(2)開啟簽名工具auto-sign,將剛才生成的apk檔案拷貝到這裡,並且其改名為update.zip,然後執行sign.bat批處理,會自動生成一個update_signed.zip檔案,這個檔案就是簽名後的檔案,可以修改為xx.apk進行安裝了
如圖 這樣的破解後的樣子,每次點選起局都會固定返回5積分,至於你問我為什麼不修改多點積分,我也想,每次修改為其他值就編譯報錯,估計是設計到安卓程式設計的設計,或者暫存器吧這個還有待研究...............另外提供的練手壓縮包內的註冊部分 我就沒該了 留給大家練手吧,把積分搞定了等於免費了,其實還可以搞其他的,如去廣告,修改資源等等
破解到這裡就基本完成了,可以看到手機軟體寫的比較簡單,我們修改一個return就ok了,隨著安卓平臺的普及,相信未來安卓平臺的趨勢將會愈發重要