[Android 逆向]frida 破解 切水果大战原版.apk
1. 手机安装该apk,运行,点击右上角礼物
提示 支付失败,请稍后重试
2. apk拖入到jadx中,待加载完毕后,搜素失败,找到疑似目标类MymmPay
的关键方法payResultFalse
4. adb logcat
或者androidstudio 查看该进程的日志,发现以下日志
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: getStringPayid7
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: ----------------------payid-----------------:7
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: ----------------------change-----------------:false
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/System.out: ----------------------paycodebefore-----------------:008
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/System.out: ----------------------paycodeafter-----------------:02
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: ----------------------paycode-----------------:008
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: ----------------------MessageUtil.getInstance().Um_Number-----------------:1
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/System.out: ----------------------strdialog0-----------------:0
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: -------totalMoney--------68.1
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: -------MessageUtil.getInstance().limitMoney--------9999.0
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/System.out: tianlibaotrue
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: paysuss-----false
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: theymoney-----20.0
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: 智能设备唯一编号为空,检查手机卡是否安装
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: bill_______________---30216141904687
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: mPaycode_____008
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei E/GameSDK: doCMCCBilling
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei V/Network: network ["ChinaNet-2qUX"] is connected.
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei V/Network: network ["ChinaNet-2qUX"] is connected.
SurfaceFlinger: duplicate layer name: changing com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei/org.cocos2dx.cpp.AppActivity to com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei/org.cocos2dx.cpp.AppActivity#1
com.mf.xxyzgame.wpp.game.hlqsgdzz.huawei I/print: onResultfailedbillingIndex008resultCode2
ps 一句,打日志还是要小心噢
从日志可以判断出,调用的地方是当前类的public void payOrder(String paramString)
public void payOrder(String paramString) {
getPayId(paramString);
Printlog("----------------------payid-----------------:" + payId);
this.mPaycode = getBillingIndexStr1(paramString);
Printlog("----------------------change-----------------:" + XmlTran.getInstance().isChange());
System.out.println("----------------------paycodebefore-----------------:" + this.mPaycode);
if (XmlTran.getInstance().isChange()) {
this.mPaycode = getBillingIndex(XmlTran.getInstance().getTranId(payId + 1));
}
System.out.println("----------------------paycodeafter-----------------:0" + XmlTran.getInstance().getTranId(payId + 1));
Printlog("----------------------paycode-----------------:" + this.mPaycode);
Printlog("----------------------MessageUtil.getInstance().Um_Number-----------------:" + MessageUtil.getInstance().Um_Number);
if (this.payType.equals("0")) {
pay();
} else if (this.payType.equals("1")) {
((Activity) this.context).runOnUiThread(new Runnable() { // from class: com.mydefinemmpay.tool.MymmPay.5
@Override // java.lang.Runnable
public void run() {
MymmPay.this.pay();
}
});
}
}
public void pay() {
if (XmlTran.getInstance().getAddDialog(payId + 1).equals("0")) {
System.out.println("----------------------strdialog0-----------------:" + XmlTran.getInstance().getAddDialog(payId + 1));
doBilling();
return;
}
......
}
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("开始支付:;\n已经消费:" + totalMoney + ";\n支付上限:" + MessageUtil.getInstance().limitMoney + ";\n商品金额:" + WinPayResult.Tmone[payId - WinPayResult.addPayCode] + ";\n支付代码:" + this.mPaycode + ";\n");
if (totalMoney >= MessageUtil.getInstance().limitMoney) {
((Activity) this.context).runOnUiThread(new Runnable() { // from class: com.mydefinemmpay.tool.MymmPay.9
@Override // java.lang.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("错误:咪咕sdk为空");
} else if (getLibKind() == 0) {
mgif.pay();
} else if (getLibKind() == 1) {
......
从日志上看,最终是走到了doBilling 的最后一个else;那么我们想办法把MessageUtil.getInstance().free
的值搞成1
是不是就ok了呢,
5. 编写frida脚本验证猜想
// lesson02.js
function main() {
Java.perform(function () {
var MessageUtilHandler = Java.use('com.mydefinemmpay.tool.MessageUtil')
if (MessageUtilHandler != undefined) {
//静态函数主动调用
var instance = MessageUtilHandler.getInstance();
console.log("===== " + JSON.stringify(instance))
//成员变量主动修改
instance.free.value = "1"
}
})
}
setTimeout(main)
6. 执行frida -UF hfdcxy.com.myapplication -l lesson02.js
执行成功,购买所有商品道具全部成功可以使用