吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 18490|回复: 38
收起左侧

[Android 原创] 火柴人联盟签名、内购破解全攻略

[复制链接]
Gordon0918 发表于 2016-6-7 15:54
小白一个,以火柴人联盟破解为例理顺下自己的思路,如果疏漏,请大牛斧正……
1、明确目标
拿到一个apk后,不要着急反编译,先在手机上试玩一下,看哪里是需要内购的以及内购的方式,手机短信验证、支付宝、微信支付等等,心中大概有个谱。以在*豆荚上下载的火柴人联盟为例,查看付费方式(苦逼的很,手机不能截屏,只能用其他手机拍照了。)如下图所示

1.jpg

可以看到支持多种付费方式,有话费支付和三方支付(支付宝、微信、银联,手机充值卡)。
2、验证软件是否有签名并进行破解
把apk扔到android killer中,反编译,不做任何操作,直接编译打包,安装到手机。此时运行程序,有如下提示
3.jpg
可以看到,二次打包后不能运行,说明它有进行签名验证。
在android killer中搜索关键字signatures,结果如下
1.jpg
wandoujia,wow,weibo是三方的sdk,不关心,直接看上述两个文件,发现关键字都是存在一个叫做getAPPSecretString的函数中,直接上java代码,逻辑是获取软件的签名后进行散列运算,然后返回一个字符串,我们此时几乎可以肯定这个东西是用于签名验证的。
1.jpg
我们大概知道了获取签名的位置是其中一个,由于软件一打开就提示是盗版,所以接下来看下主流程。入口是com.DBGame.DiabloLOL.SplashActivity;查看它的oncreate函数,发现它是调用了DiabloLOL的activity,我们主要看DiabloLOL.smali文件,oncreate函数如下
[Java] 纯文本查看 复制代码
protected void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    init();
    Bluetooth.getInstance().init(this);
    this.context = this;
    BLHelper.init(this.aHandler, this);
    MobClickCppHelper.init(this);
    this.wandouGamesApi = CmgameApplication.getWandouGamesApi();
    this.wandouGamesApi.init(this);
    try
    {
      ReYun.initWithKeyAndChannelId(this, "a4d2f6135f92a14d5d86da48f095e823", BLHelper.getEmChannel());
[color=#ff0000]      new AddBlackName(this);[/color]
[color=#ff0000]      AddBlackName.Check();[/color]
      instance = this;
      paramBundle = ((TelephonyManager)getSystemService("phone")).getSimOperator();
      if (((paramBundle != null) && (paramBundle.trim().equals("46001"))) || (paramBundle.trim().equals("50501")))
      {
        i = 2;
        this.iFromPay = i;
        if (i != 2) {
          EMPayManager.initMerge(this, 1, 2);
        }
        MatchVSHelper.init(this.aHandler, this);
        return;
      }
    }
    catch (Exception paramBundle)
    {
      for (;;)
      {
        int i;
        paramBundle.printStackTrace();
        continue;
        if ((paramBundle != null) && (paramBundle.trim().equals("46003"))) {
          i = 1;
        } else {
          i = 0;
        }
      }
    }
  }
  
看到一个AddBlackName.Check(); 而且addblackName正好是我们上面找到那个两个包括getAPPSecretString类中的一个,感觉棒棒哒,赶紧跟进去,代码很简单,只上关键代码
[Java] 纯文本查看 复制代码
  str3 = ((WifiManager)AddBlackName.mContext.getSystemService("wifi")).getConnectionInfo().getMacAddress();
          str2 = String.format("X-Em-Apk-Certifiction%s", new Object[] { utils.getAPPSecretString(AddBlackName.mContext) });
          AddBlackName.loadData(String.format("http://119.29.20.199/stickman/api/v1/sign/confirmSign?did=%s&appkey=%s&ver=%s&ch=%s&lang=%s&pkgname=%s&mac=%s&sdkver=%s&sign=%s", new Object[] { str1, AddBlackName.sKey, Integer.valueOf(i), AddBlackName.sChannel, AddBlackName.sLanguage, AddBlackName.mContext.getPackageName(), str3, "1.0.0", str2 }));


获取软件签名后调用loadData函数,传进去的还有个网址,大概可以判断是进行网络验证,跟进去看看,流程也很命令,不再贴代码,大概就是构造一个http包,发到服务器,经过服务器验证,返回状态。当返回状态为1103时,认为是校验失败
[Java] 纯文本查看 复制代码
          if (updateItem.getStatus() == 1103)
          {
            updateItem.setTitle(paramString.getString("authTitle"));
            updateItem.setDescription(paramString.getString("authDesc"));
          }
          PreferUtil.saveIntValue(mContext, "BLACK_ITATUS", updateItem.getStatus());
          PreferUtil.saveStrValue(mContext, "BLACK_STITLE", updateItem.getTitle());
          PreferUtil.saveStrValue(mContext, "BLACK_SMESSAGE", updateItem.getDescription());
          PreferUtil.saveStrValue(mContext, "BLACK_SURL", updateItem.getLink());
          if (updateItem.getStatus() == 1103) {
            mHandler.sendEmptyMessage(1000);

OK,知道大概流程就好办了只需要搜索1103关键字,看哪里进行修改了,修改下if跳转即可。修改方法不再赘述,感兴趣的同学可下载样本比对。修改完成后可正常运行。
3、内购破解
3.1 话费支付破解
软件签名破解完成后,接下来进行内购破解,在不少文章中可到内购破解方式是搜索payCancel、payFailed、onBilling等关键字。试着搜索了,这些关键字都有,但是修改后并没有起作用。后来想了下,这些关键字都是三方sdk中计费成功和失败的标记,而在这个软件中,包含的
三方计费sdk太多了,有移动、联通、三方支付,如下所示
1.jpg
大概看了下其中的逻辑,在common中的EMPayManager类initMerge方法中进行运营商判断,然后根据运营商不同实例化下面的实例,
[Java] 纯文本查看 复制代码
  public static void initMerge(Context paramContext, int paramInt1, int paramInt2)
  {
    String str = ((TelephonyManager)paramContext.getSystemService("phone")).getSimOperator();
    if (((str != null) && (str.trim().equals("46001"))) || (str.trim().equals("50501"))) {
      EMUnicomManager.init(paramContext);
    }
    for (;;)
    {
      return;
      if ((str != null) && (str.trim().equals("46003"))) {
        EMEGamePayManager410.init(paramContext);
      } else if (paramInt2 == 0) {
        EMMMBillingManager.getInstance().init(paramContext);
      } else if (paramInt2 == 1) {
        EMMMIntenetManager.getInstance(paramContext).init(paramContext, new OnLoginFinishListener()
        {
          public void onLoginFinish(int paramAnonymousInt) {}
        });
      } else {
        EMSohuPayManager.init((Activity)paramContext);
      }
    }
  }
  

如果修改每个计费sdk的接口会比较麻烦,我们回到主逻辑DiaboLOL,在文件开头定义了一个handler,主要代码有
[Java] 纯文本查看 复制代码
  EMPayManager.payMerge(DiabloLOL.this, DiabloLOL.this.PRO_ID[DiabloLOL.this.mPayIndex], DiabloLOL.this.PAY_RMB[DiabloLOL.this.mPayIndex], DiabloLOL.this.PAY_CODE_UNICOM[DiabloLOL.this.mPayIndex], DiabloLOL.this.PAY_CODE_SMS[DiabloLOL.this.mPayIndex], DiabloLOL.this.PAY_NAME[DiabloLOL.this.mPayIndex], DiabloLOL.this.PAY_CODE_MM[DiabloLOL.this.mPayIndex], 2, 0, null, false, "shit", new OnPayFinishListener()
          {
            public void onPayFinish(int paramAnonymous2Int)
            {
              if (paramAnonymous2Int == 1)
              {
                Log.e("test", "rechager sucess");
                DiabloLOL.this.setPayment();
                BLHelper.purchaseComplete(DiabloLOL.this.PRO_ID_Str[DiabloLOL.this.mPayIndex], 1);
                BLHelper.closeShieldLayer();
              }
              for (;;)
              {
                return;
                Log.e("test", "rechager failure");
                BLHelper.closeShieldLayer();
                System.out.println("������������");
              }
            }

调用 EMPayManager的payMerge函数,新建监听器作为参数,跟进去payMerge,是根据运营商不同,调用不同计费sdk的pay接口,并把监听器传进去。如果跟进每个计费接口,会发现每个接口最终都会调用监听器的onPayFinish接口,那么
我们只需要修改onPayFinish接口,使参数恒为1即可。
3.2 三方支付破解
上一步骤搞定了话费内购,接下来在主逻辑中发现一个可疑方法 PayThird ,实现了onfailed和onSuccess方法,把onfailed中的内容全部删除,然后把onSuccess中的内容拷贝进去。测试,发现三方支付的内购也成功破解了,如下
[Java] 纯文本查看 复制代码
  public void PayThird(String paramString)
  {
    Log.e("lihytest", "orderNum " + paramString);
    long l = this.PAY_RMB[this.mPayIndex];
    this.wandouGamesApi.pay(this, this.PAY_NAME[this.mPayIndex], l, paramString, new OnPayFinishedListener()
    {
      public void onPayFail(PayResult paramAnonymousPayResult)
      {
        Log.e("asd", "onPayFail");
        BLHelper.closeShieldLayer();
      }
      
      public void onPaySuccess(PayResult paramAnonymousPayResult)
      {
        Log.e("asd", "onPaySuccess");
        ReYun.setPayment("unkown", "wdj151", "RMB", DiabloLOL.this.PAY_RMB[DiabloLOL.this.mPayIndex] / 100.0F, 0.0F, DiabloLOL.this.PAY_NAME[DiabloLOL.this.mPayIndex], 0L, 0);
        BLHelper.purchaseComplete(DiabloLOL.this.PRO_ID_Str[DiabloLOL.this.mPayIndex], 2);
        BLHelper.closeShieldLayer();
      }
    });
  }

打开smali代码,把onPaySucess中的部分拷贝到onPayFailed中即可。
其实。。。这个破解的有点侥幸,具体逻辑现在也没有搞明白,所以有时候运气来了挡都挡不住
看下成果吧
2.jpg


4 总结
1、对于签名验证,有本地验证和网络验证,可以根据不联网时能不能正常运行来判断
2、对于单一模式的付费方式,最好看一下是使用的是那种计费sdk,然后取开发者网站看下该sdk的重要接口
3、对于多种模式的付费方式,查找调用计费接口的统一入口。

PS:仅供技术交流,请勿传播破解软件






免费评分

参与人数 8威望 +2 吾爱币 +2 热心值 +8 收起 理由
cappie + 1 + 1 受教了。。。
bibi + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
耀哥@宋耀 + 1 我很赞同!
Czw + 1 热心回复!
Cizel + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
renfeng + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qtfreet00 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
r1342018996 + 1 佩服

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

1461244950 发表于 2016-6-7 22:28
其实火柴人联盟和游戏的比较好破解  直接手机mt apk搜onResult方法名  找到对应数据 把失败改成成功即可

再搜索侵权相关字符串 找到验证代码  删除所有代码保留返回代码即可 否则闪退

再进xml里面去除sms短信发送权限 即可 完美内购去验证破解  楼主的方法比较详细 多学习学习
qfwfq2015 发表于 2016-6-7 20:24
感谢发布原创作品,吾爱破解论坛因你更精彩!
很久以前玩过这个游戏  当时破解的方案就是 设置软件使用权限 将此程序的联网功能关闭  然后就随心所欲的当单机游戏玩了  买钻石 金币 英雄都不会扣费了 不知道现在这游戏是不还是这么好破解
倾听回忆 发表于 2016-6-7 16:01
多谢楼主分享   如果能做个秒杀版再好不过了
 楼主| Gordon0918 发表于 2016-6-7 16:09
抱歉,忘记发样本链接了
http://pan.baidu.com/s/1bozuVaZ
xnu5
ghshr521 发表于 2016-6-7 16:19
感谢楼主分享多多学习!
asd9988 发表于 2016-6-7 16:31
预计应该会优秀鼓励,可惜人太少了。加油楼主。
我是小白我自豪 发表于 2016-6-7 19:40 来自手机
辣么看llalaaalla
moumoe 发表于 2016-6-7 19:54
此时几乎可以肯定这个东西是用于签名验证的。 病句
a5680497 发表于 2016-6-7 20:02
赞一个,楼主威武
16zjs 发表于 2016-6-7 20:04
感谢发布原创作品,吾爱破解论坛因你更精彩!
fz74110 发表于 2016-6-7 20:08
谢谢分享,学习了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-14 19:55

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表