安卓逆向(Android)之二__《全民捕魚》遊戲內購破解

安卓逆向之二__《全民捕魚》遊戲內購破解

 

環境簡介

系統:Android 4.4
工具:Windows 10 64bit 夜神模擬器
        Android Killer

        Java Decompiler

 

全民捕魚遊戲簡介

遊戲名稱:全民捕魚
遊戲類型:休閒益智
遊戲版本:1.7

遊戲界面如下:

 

逆向分析

首先我們進入商城點擊付費金幣的購買,彈出"購買失敗"的Toast(吐司)

根據這個提示我們使用AndroidKiller分析這個APK.看到入口函數爲LogoActivity很簡單.

直接使用特徵Toast字符串搜索,沒有搜到.

再次測試把字符串轉換爲UniCode形式(下邊的小a大A按鈕),再次搜索,找到一個字符串結果

雙擊到使用處的語句,查看源碼發現此處有購買成功失敗函數的選擇調用語句

我們通過這幾個函數繼續查找對比,最後在搜索payFail的最後一個結果,發現重要函數所在

支付失敗,與支付成功函數離得很近,分析發現,函數參數也相似

所以我們使用的破解內購的辦法可以是,把支付成功函數的函數體,整個複製到支付失敗函數裏邊去,讓支付永遠成功.

兩個函數smali代碼

.method public payFailed(Ljava/util/Map;I)V
    .locals 5
    .param p1, "params"    # Ljava/util/Map;
    .param p2, "arg1"    # I

    .prologue
    .line 208
    const-string v0, "cocos2d-x debug info"

    new-instance v1, Ljava/lang/StringBuilder;

    invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V

    const-string v2, "Failed DX_payCode2 == "

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v1

    sget-object v2, Lcom/payCom/org/IAPListener;->DX_PAYCODES:[Ljava/lang/String;

    iget-object v3, p0, Lcom/payCom/org/IAPListener$1;->this$0:Lcom/payCom/org/IAPListener;

    iget v3, v3, Lcom/payCom/org/IAPListener;->curPayIndex:I

    aget-object v2, v2, v3

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 209
    const-string v0, "cocos2d-x debug info"

    new-instance v1, Ljava/lang/StringBuilder;

    invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V

    const-string v2, "FaildCode == "

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v1

    invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 210
    iget-object v0, p0, Lcom/payCom/org/IAPListener$1;->this$0:Lcom/payCom/org/IAPListener;

    iget v0, v0, Lcom/payCom/org/IAPListener;->curPayIndex:I

    const/4 v1, 0x0

    invoke-static {v0, v1}, Lcom/payCom/org/GameJni;->OderFinish(II)V

    .line 211
    sget-object v0, Lcom/payCom/org/IAPListener;->iapHandler:Lcom/payCom/org/IAPHandler;

    sget-object v1, Lcom/payCom/org/IAPListener;->iapHandler:Lcom/payCom/org/IAPHandler;

    const/16 v2, 0x2715

    sget-object v3, Lcom/payCom/org/IAPListener;->DX_PAYCODES:[Ljava/lang/String;

    iget-object v4, p0, Lcom/payCom/org/IAPListener$1;->this$0:Lcom/payCom/org/IAPListener;

    iget v4, v4, Lcom/payCom/org/IAPListener;->curPayIndex:I

    aget-object v3, v3, v4

    invoke-static {v1, v2, v3}, Landroid/os/Message;->obtain(Landroid/os/Handler;ILjava/lang/Object;)Landroid/os/Message;

    move-result-object v1

    invoke-virtual {v0, v1}, Lcom/payCom/org/IAPHandler;->sendMessage(Landroid/os/Message;)Z

    .line 212
    return-void
.end method

.method public paySuccess(Ljava/util/Map;)V
    .locals 5
    .param p1, "params"    # Ljava/util/Map;

    .prologue
    .line 202
    const-string v0, "cocos2d-x debug info"

    new-instance v1, Ljava/lang/StringBuilder;

    invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V

    const-string v2, "Success DX_payCode1"

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v1

    sget-object v2, Lcom/payCom/org/IAPListener;->DX_PAYCODES:[Ljava/lang/String;

    iget-object v3, p0, Lcom/payCom/org/IAPListener$1;->this$0:Lcom/payCom/org/IAPListener;

    iget v3, v3, Lcom/payCom/org/IAPListener;->curPayIndex:I

    aget-object v2, v2, v3

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 203
    iget-object v0, p0, Lcom/payCom/org/IAPListener$1;->this$0:Lcom/payCom/org/IAPListener;

    iget v0, v0, Lcom/payCom/org/IAPListener;->curPayIndex:I

    const/4 v1, 0x1

    invoke-static {v0, v1}, Lcom/payCom/org/GameJni;->OderFinish(II)V

    .line 204
    sget-object v0, Lcom/payCom/org/IAPListener;->iapHandler:Lcom/payCom/org/IAPHandler;

    sget-object v1, Lcom/payCom/org/IAPListener;->iapHandler:Lcom/payCom/org/IAPHandler;

    const/16 v2, 0x271a

    sget-object v3, Lcom/payCom/org/IAPListener;->DX_PAYCODES:[Ljava/lang/String;

    iget-object v4, p0, Lcom/payCom/org/IAPListener$1;->this$0:Lcom/payCom/org/IAPListener;

    iget v4, v4, Lcom/payCom/org/IAPListener;->curPayIndex:I

    aget-object v3, v3, v4

    invoke-static {v1, v2, v3}, Landroid/os/Message;->obtain(Landroid/os/Handler;ILjava/lang/Object;)Landroid/os/Message;

    move-result-object v1

    invoke-virtual {v0, v1}, Lcom/payCom/org/IAPHandler;->sendMessage(Landroid/os/Message;)Z

    .line 205
    return-void
.end method

修改完成後,保存,並重新編譯

在夜神模擬器上卸載之前的原版遊戲,安裝破解後的遊戲,實現了商城內購破解

 

添加個人信息的破解

爲了更有趣一點,我們在購買成功的提示上添加自己的個人信息

我們再次搜索到"購買成功"提示,在字符串之前加入"Hades破解:",如下,最後再次編譯,安裝測試

完成破解:

總結:

安卓遊戲內購的破解簡單的思路都是大同小異,也可以更改調用的函數參數等.smail代碼與僞Java代碼很接近自然語言邏輯思路,在沒有安卓加固(殼)的遊戲上做一些內購破解還是很簡單的.去網上Download幾個遊戲練習一下破解就很有成就感.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章