(文章仅用于记录学习过程,相关破解技术仅限于研究使用,不准用于非法目的,否则后果自负)
说明
学习逆向基础之后就开始真实实战,这边我是跟着这篇文章看到逆向资源,虽然文章是17年的文章,但是毕竟是在学习吗,不要管时间勒.这里采用和文章不同的方法
使用工具
1:apltool
2: jadx
3:sublime Text2
看源码
这个apk是一个简单的切水果应用,并没有加壳,我们直接将apk拖进jadx里面去
我们打开将失败字符串转为unicode,也就是\u5931\u8d25,(ps:失败怎么来的,可以玩下游戏点下支付然后取消)我们搜索看看
我们看到这个命名,com.mydefinemmpay.tool.Mymmpay,这个明显就是一个管理支付的类,
我们接着看下哪里调用了payResultSuccees(),我们看到在当前类的doBilling方法调用了payResultSuccees,也就是同一个类下面
//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();
}
}
}
}
我们看下谁调用了doBilling方法,我们看到是当前类的pay方法调用了doBilling//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();
}
整理思路
我们发现MymmPay这个是负责管理支付的,这个里面有pay(),doBilling(),payResultSucceed(),payResultFalse(),payResultCancel()等主要方法,整理下逻辑,点击支付,然后调用pay(),pay调用dobilling方法,然后返回结果整理方法
有好几种方法
1:原文说的,将payResultFalse()内容替换成payResultSucceed的内容,这样支付失败和支付成功是一样都是成功,
2:pay->doBilling->我们看了下源码,doBillding()里面调用了payResultSucceed(),payResultCancel().payResultFalse(),这个类应该是一个判断类,我们直接把doBilling()内部直接调用payResultSuccess()方法,这样连判断都不用判断了
反编译
使用apktool命令将apk反编译,fruit文件夹,我这边的apk命名是fruit.apk,所以就生成了fruit文件夹,如果你不是叫fruit那就是其他文件名
apktool d fruit.apk
我们找MymmPay这个类的,这个类在com.mydefinemmpay.tool文件下面,打开fruit->smali->com->mydefinemmpay->tool下面
我们使用sublime Text打开MymmPay.smali(sublime text增加了smali语法高亮和提示的支持,需要的童鞋可以自己百度一下,这边就不说)
我们搜索下doBilling
//方法开头 修改前
.method public doBilling()V
.locals 7
.prologue
//中间省略
//方法结尾
.end method
将方法中间删掉,然后将locals 修改为0,然后在增加payResultSuccess()方法的调用
///修改后
.method public doBilling()V
.locals 0
.prologue
//其他的不要 只增加一条方法
//只调用payResultSuccess()方法就可以
invoke-virtual {v0}, Lcom/mydefinemmpay/tool/MymmPay;->payResultSuccess()V
return-void
.end method
完成
之后就保存,然后使用apktool重新打包生成apk文件,然后使用jarsigner重新签名安装就可以了