0元购买某游戏648元点券

## 前言 在游戏中要想玩的畅快,免不了装备的购买,而前提是要有足够的点券支撑。本文将对某游戏,实现0元购买648元点券,仅供学习使用。 ## 购买点券 点券购买界面如图所示。 [![](htt...

前言

在游戏中要想玩的畅快,免不了装备的购买,而前提是要有足够的点券支撑。本文将对某游戏,实现0元购买648元点券,仅供学习使用。

购买点券

点券购买界面如图所示。

查看程序log信息

利用工具Android Device Monitor查看程序log信息。

选中包名,并在过滤器添加包名进行过滤。

点击进入充值60点券页面后,查看日志。

发现返回的都是json数据,而json数据是通过网络返回的,并没有硬编码在smali代码里面。所以这些并不是我们想要的。

点击返回键后,再次查看日志。

发现日志中有一个很明显的"取消支付操作"字符串,但这个字符串同样是json格式,很大概率来自于网络。

在Android Killer中进行反编译,然后在工程搜索中将"取消支付操作"转换为Unicode后进行搜索。

果然并未搜索到任何结果。在log日志中,还有一处硬编码字符串为"4399充值返回:6001"。

同样,将"4399充值返回:6001"转换为Unicode后进行搜索。

仍然没有搜索到任何结果,尝试将返回码6001去除,只将字符串"4399充值返回:"转换为Unicode后进行搜索。

成功在smali.com.leiting.sdk.channel.m4399.M4399SdkUser$4.smali处搜索到结果。

方法剖析

将APK拖入到jadx-gui工具中进行反编译,以便于更方便的查看smali对应的java代码。

找到smali.com.leiting.sdk.channel.m4399.M4399SdkUser$4.smali处,对应Java代码如下:

private OperateCenter.OnRechargeFinishedListener mPayListener = new OperateCenter.OnRechargeFinishedListener() {
  /* class com.leiting.sdk.channel.m4399.M4399SdkUser.AnonymousClass4 */

  @Override // cn.m4399.operate.OperateCenter.OnRechargeFinishedListener
  public void onRechargeFinished(boolean z, int i, String str) {
    Message obtainMessage = M4399SdkUser.this.mHandler.obtainMessage();
    String str2 = ConstantUtil.TAG;
    BaseUtil.logDebugMsg(str2, "4399充值返回:" + i);
    if (!z || i != 9000) {
      Bundle bundle = new Bundle();
      bundle.putString("resultMsg", str);
      obtainMessage.what = 6;
      obtainMessage.setData(bundle);
    } else {
      obtainMessage.what = 5;
    }
    M4399SdkUser.this.mHandler.sendMessage(obtainMessage);
  }
};

通过代码分析得出,返回的字符串是"4399充值返回:"加上传入的参数i。

而我们通过日志收集到的信息为"4399充值返回:6001"。

所以推测,进入if (!z || i != 9000)分支语句后,则充值不成功。

进入else分支语句后,充值成功。

根据逻辑得出,else与if是相对的,所以只要满足 z && i == 9000 即可充值成功。

所以首先要找到参数z和i的值。

利用工具Android Device Monitor进行方法剖析。

点击start Method Profiling,然后在支付页面点击返回,捕捉这段时间的方法都执行了哪些方法。

因为在返回过程中一定调用了onRechargeFinished方法,所以在Find中搜索onRechargeFinished。

其中Parents表示调用它的方法,Children表示它调用的方法,依次类推找出调用关系为:

cn.m4399.recharge.ui.activity.RechargeActivity.d()
    ↓
cn.m4399.operate.x0$d.a
    ↓
com.leiting.sdk.channel.m4399.M4399SdkUser$4.onRechargeFinished

修改smali

通过方法剖析找到最初的代码调用位置为:cn.m4399.recharge.ui.activity.RechargeActivity.d()。

对应java代码为:

private void d() {
  if (!b4.g() && a3.e != null) {
    a3.e.a(false, 6001, PayResult.a(6001));
  }
}

继续往下跟踪,找到cn.m4399.operate.x0$d.a对的Java代码为:

public class d implements a3.g {
  d() {
  }

  @Override // cn.m4399.operate.a3.g
  public void a(boolean z, int i, String str) {
    x0.this.e.onRechargeFinished(z, i, str);
  }
}

因为只有前两个参数对充值结果有影响,所以第三个参数不做研究。前两个参数中,z为false,i为6001。

而想要充值结果成功,需要满足:z为true,并且,i==9000。

z是第一个参数,所以在判断p1是否等于0之前,将1赋值给p1。

由于增加了代码,令p1=1,所以继续执行第75行代码。

第75行代码,令p1=0x2328。将0x2328换算成十进制为9000。

然后执行第77行代码,如果p2不等于p1就会跳转到:cond_0处。

已知i是第二个参数,p2的值是6001,而p1的值是9000。所以一定是不相等的。

而只有p2和p1相等的时候,才会充值成功。所以将6001转换为十六进制后赋值给p1。

成功内购

修改之后保存,进行回编译。安装后登入游戏,选择价值648元的点券购买,然后返回即可购买成功。

总结

利用Android Device Monitor工具查看程序每一步执行时打印的log信息,通过搜集到最有可能存在的硬编码信息进行逐一尝试,摸清代码编写方式。再通过方法剖析的方式,分析出各个方法之间的调用关系,最后通过读smali代码的逻辑找到关键语句处进行添加和修改。完成0元可购买任何点券。

  • 发表于 2021-12-07 09:43:15
  • 阅读 ( 8522 )
  • 分类:漏洞分析

0 条评论

请先 登录 后评论
bmstd
bmstd

13 篇文章

站长统计