安卓逆向--簡單游戲破解

(文章僅用于記錄學(xué)習(xí)過程,相關(guān)破解技術(shù)僅限于研究使用,不準(zhǔn)用于非法目的,否則后果自負(fù))

說明

學(xué)習(xí)逆向基礎(chǔ)之后就開始真實(shí)實(shí)戰(zhàn),這邊我是跟著這篇文章看到逆向資源,雖然文章是17年的文章,但是畢竟是在學(xué)習(xí)嗎,不要管時(shí)間勒.這里采用和文章不同的方法

使用工具

1:apltool
2: jadx
3:sublime Text2

看源碼

這個(gè)apk是一個(gè)簡單的切水果應(yīng)用,并沒有加殼,我們直接將apk拖進(jìn)jadx里面去


image.png

我們打開將失敗字符串轉(zhuǎn)為unicode,也就是\u5931\u8d25,(ps:失敗怎么來的,可以玩下游戲點(diǎn)下支付然后取消)我們搜索看看

image.png

我們看到這個(gè)命名,com.mydefinemmpay.tool.Mymmpay,這個(gè)明顯就是一個(gè)管理支付的類,

看下后面的方法payResultFalse,這是支付失敗的意思嗎?我們點(diǎn)進(jìn)去看看,這邊有3個(gè)方法,分別是支付成功,支付失敗,支付取消,看來我們找對(duì)了類,這個(gè)類就是管理支付的
方法名

我們接著看下哪里調(diào)用了payResultSuccees(),我們看到在當(dāng)前類的doBilling方法調(diào)用了payResultSuccees,也就是同一個(gè)類下面
這邊調(diào)用了
//doBilling方法
public void doBilling() {
        float totalMoney = Float.valueOf(RecordOpreate.getInstance().getData(RecordOpreate.totalMoey)).floatValue();
        Printlog("-------totalMoney--------" + totalMoney);
        Printlog("-------MessageUtil.getInstance().limitMoney--------" + MessageUtil.getInstance().limitMoney);
        WinPayResult.getInstance();
        this.payCodeMoney = WinPayResult.Tmone[payId - WinPayResult.addPayCode];
        showDebug("\u5f00\u59cb\u652f\u4ed8\uff1a;\n\u5df2\u7ecf\u6d88\u8d39\uff1a" + totalMoney + ";\n" + "\u652f\u4ed8\u4e0a\u9650\uff1a" + MessageUtil.getInstance().limitMoney + ";\n" + "\u5546\u54c1\u91d1\u989d\uff1a" + WinPayResult.Tmone[payId - WinPayResult.addPayCode] + ";\n" + "\u652f\u4ed8\u4ee3\u7801\uff1a" + this.mPaycode + ";\n");
        if (totalMoney >= MessageUtil.getInstance().limitMoney) {
            ((Activity) this.context).runOnUiThread(new Runnable() {
                public void run() {
                    MymmPay.this.payResultSuccess();
                }
            });
        } else if (this.onlineNumName.equals("EMPTY")) {
            payResultSuccess();
        } else {
            System.out.println("tianlibao" + tanLibao());
            if (!tanLibao()) {
                payResultFalse();
            } else if (MessageUtil.getInstance().free.equals("1")) {
                payResultSuccess();
            } else {
                Printlog("paysuss-----" + this.paysuss);
                Printlog("theymoney-----" + WinPayResult.Tmone[payId - WinPayResult.addPayCode]);
                String sdkKind = MessageUtil.getInstance().sdkKind;
                if (sdkKind.equals("0")) {
                    if (mgif == null) {
                        showDebug("\u9519\u8bef\uff1a\u54aa\u5495sdk\u4e3a\u7a7a");
                    } else if (getLibKind() == 0) {
                        mgif.pay();
                    } else if (getLibKind() == 1) {
                        if (this.cardKind != 0) {
                            osif.pay();
                        } else if (this.migfalseTime >= 1) {
                            osif.pay();
                        } else {
                            mgif.pay();
                        }
                    } else if (getLibKind() == 2) {
                        osif.pay();
                    }
                }
                if (sdkKind.equals("1")) {
                    if (osif == null) {
                        showDebug("\u9519\u8bef\uff1aothersdk\u4e3a\u7a7a");
                    } else if (getLibKind() == 0) {
                        osif.pay();
                    } else if (this.cardKind == 0) {
                        mgif.pay();
                    } else {
                        osif.pay();
                    }
                }
                if (sdkKind.equals("2")) {
                    if (osif2 == null) {
                        showDebug("\u9519\u8bef\uff1aother2\u4e3a\u7a7a");
                    } else {
                        osif2.pay();
                    }
                }
                if (sdkKind.equals("3")) {
                    if (osif3 == null) {
                        showDebug("\u9519\u8bef\uff1aother3sdk\u4e3a\u7a7a");
                    } else {
                        osif3.pay();
                    }
                }
                if (!sdkKind.equals("4")) {
                    return;
                }
                if (osif4 == null) {
                    showDebug("\u9519\u8bef\uff1aother4sdk\u4e3a\u7a7a");
                } else {
                    osif4.pay();
                }
            }
        }
    }

我們看下誰調(diào)用了doBilling方法,我們看到是當(dāng)前類的pay方法調(diào)用了doBilling
image.png
//pay方法
public void pay() {
        if (XmlTran.getInstance().getAddDialog(payId + 1).equals("0")) {
            System.out.println("----------------------strdialog0-----------------:" + XmlTran.getInstance().getAddDialog(payId + 1));
            doBilling();
            return;
        }
        System.out.println("----------------------strdialog1-----------------:" + XmlTran.getInstance().getAddDialog(payId + 1));
        if (MessageUtil.getInstance().Um_Number.equals("1")) {
            Printlog("--------------00000000000----------------");
            new Builder(this.context).setMessage(XmlTran.getInstance().getAddDialog(payId + 1)).setPositiveButton("\u8d2d\u4e70", new OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    MymmPay.this.doBilling();
                }
            }).setOnKeyListener(new OnKeyListener() {
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == 4 && event.getRepeatCount() == 0) {
                        MymmPay.this.payResultFalse();
                    }
                    return false;
                }
            }).setNegativeButton("\u53d6\u6d88", new OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    MymmPay.this.payResultFalse();
                }
            }).show();
            return;
        }
        doBilling();
    }


整理思路

我們發(fā)現(xiàn)MymmPay這個(gè)是負(fù)責(zé)管理支付的,這個(gè)里面有pay(),doBilling(),payResultSucceed(),payResultFalse(),payResultCancel()等主要方法,整理下邏輯,點(diǎn)擊支付,然后調(diào)用pay(),pay調(diào)用dobilling方法,然后返回結(jié)果
image.png

整理方法

有好幾種方法

1:原文說的,將payResultFalse()內(nèi)容替換成payResultSucceed的內(nèi)容,這樣支付失敗和支付成功是一樣都是成功,

2:pay->doBilling->我們看了下源碼,doBillding()里面調(diào)用了payResultSucceed(),payResultCancel().payResultFalse(),這個(gè)類應(yīng)該是一個(gè)判斷類,我們直接把doBilling()內(nèi)部直接調(diào)用payResultSuccess()方法,這樣連判斷都不用判斷了

反編譯

使用apktool命令將apk反編譯,fruit文件夾,我這邊的apk命名是fruit.apk,所以就生成了fruit文件夾,如果你不是叫fruit那就是其他文件名

apktool d fruit.apk
反編譯結(jié)果

我們找MymmPay這個(gè)類的,這個(gè)類在com.mydefinemmpay.tool文件下面,打開fruit->smali->com->mydefinemmpay->tool下面

image.png

我們使用sublime Text打開MymmPay.smali(sublime text增加了smali語法高亮和提示的支持,需要的童鞋可以自己百度一下,這邊就不說)

我們搜索下doBilling

//方法開頭 修改前
.method public doBilling()V
    .locals 7
   .prologue
  //中間省略

//方法結(jié)尾
.end method

將方法中間刪掉,然后將locals 修改為0,然后在增加payResultSuccess()方法的調(diào)用

///修改后
.method public doBilling()V
    .locals 0
    .prologue
    //其他的不要 只增加一條方法
    //只調(diào)用payResultSuccess()方法就可以
    invoke-virtual {v0}, Lcom/mydefinemmpay/tool/MymmPay;->payResultSuccess()V

return-void
.end method

完成

之后就保存,然后使用apktool重新打包生成apk文件,然后使用jarsigner重新簽名安裝就可以了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子切揭,更是在濱河造成了極大的恐慌,老刑警劉巖坝撑,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厉碟,死亡現(xiàn)場(chǎng)離奇詭異查库,居然都是意外死亡籍凝,警方通過查閱死者的電腦和手機(jī)周瞎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來静浴,“玉大人堰氓,你說我怎么就攤上這事挤渐∑幌恚” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵浴麻,是天一觀的道長得问。 經(jīng)常有香客問我,道長软免,這世上最難降的妖魔是什么宫纬? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮膏萧,結(jié)果婚禮上漓骚,老公的妹妹穿的比我還像新娘。我一直安慰自己榛泛,他們只是感情好蝌蹂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著曹锨,像睡著了一般孤个。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沛简,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天齐鲤,我揣著相機(jī)與錄音斥废,去河邊找鬼。 笑死给郊,一個(gè)胖子當(dāng)著我的面吹牛牡肉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播淆九,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼荚板,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了吩屹?” 一聲冷哼從身側(cè)響起跪另,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煤搜,沒想到半個(gè)月后免绿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡擦盾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年嘲驾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迹卢。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辽故,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腐碱,到底是詐尸還是另有隱情誊垢,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布症见,位于F島的核電站喂走,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谋作。R本人自食惡果不足惜芋肠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遵蚜。 院中可真熱鬧帖池,春花似錦、人聲如沸吭净。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽攒钳。三九已至帮孔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背文兢。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工晤斩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姆坚。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓澳泵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親兼呵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子兔辅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354