贪吃蛇大作战-反编译

贪吃蛇大作战

此文只做Android app反编译分析,如有损害武汉微派网络科技有限公司的利益,请告知我删除。


最近玩了一款很火的游戏贪吃蛇大作战,无奈花了将近一小时,分数才到2W多一点,查看世界排名最高的都是30多W,如此马拉松式玩法,真是牛逼。所以我觉得研究一下,Google 一把,贪吃蛇大作战刷分

该刷分脚本是python语言,模拟http请求达到刷分目的,git下来,fiddler抓包,替换自己的uid

	secret = '/TzSbON46vSq88gJyzosplEIoDyMpssbFDCj&'
root_url = 'http://snakeapi.afunapp.com/'
path = 'top_list_v2/update_score'
url = root_url + path
data = {'device_id': 'XXX',
        'game_mode': '1',
        'kill': '1',
        'length': '1',
        'market': 'apple',
        'platform': '1',
        'push_channel': '1',
        'push_id': '111111111222222223333333344444444',
        'sid': 'XXX',
        'uid': 'XXX',
        'version': '2.1'}

点击run 提示snake_sign 签名不对。。。其实我并不懂python,也没研究出脚本里加密算法是什么,所以准备反编译看能不能在代码里找些什么。

反编译

反编译工具用的Android Killer,貌似好久没更新了,有需要的自行google。173735_bArU_2438532.png代码尽然没有混淆,此路很畅通。。。先找主要的代码看,GameActivity.calss就是它了,并没有找到关于加密方面的信息。

  public static void post(String paramString, HashMap<String, String> paramHashMap, ResponseHandlerInterface paramResponseHandlerInterface)
  {
    if (client == null) {
      client = new AsyncHttpClient();
    }
    Object localObject = paramHashMap;
    if (paramHashMap == null) {
      localObject = new HashMap();
    }
    ((HashMap)localObject).put("platform", "2");
    ((HashMap)localObject).put("version", PacketUtil.getVersionName());
    ((HashMap)localObject).put("version_code", PacketUtil.getVersionCode() + "");
    ((HashMap)localObject).put("device_id", DeviceIdHelper.getDid());
    ((HashMap)localObject).put("market", PacketUtil.getChannel());
    ((HashMap)localObject).put("channel", PacketUtil.getChannel());
    ((HashMap)localObject).put("push_channel", PushServiceUtil.getPushChannel() + "");
    String str = PushServiceUtil.getPushId();
    paramHashMap = str;
    if (TextUtils.isEmpty(str)) {
      paramHashMap = "111111111222222223333333344444444";
    }
    ((HashMap)localObject).put("push_id", paramHashMap);
    paramHashMap = LoginHelper.getUid();
    if (!TextUtils.isEmpty(paramHashMap))
    {
      ((HashMap)localObject).put("uid", paramHashMap);
      ((HashMap)localObject).put("sid", LoginHelper.getSid());
    }
    doSign(paramString, (HashMap)localObject);
    paramHashMap = map2RequestParams((HashMap)localObject);
    Log.d(TAG, "网络请求-->" + paramString + "    参数-->" + paramHashMap.toString());
    client.post(paramString, paramHashMap, paramResponseHandlerInterface);
  }

post公用请求方法,其中doSign(paramString, (HashMap)localObject)就是参数加密方法

private static void doSign(String paramString, HashMap<String, String> paramHashMap)
  {
    paramString = paramString.substring(UrlConfig.K_API_URL.length());
    Object localObject1 = new ArrayList();
    Object localObject2 = paramHashMap.entrySet().iterator();
    while (((Iterator)localObject2).hasNext())
    {
      Map.Entry localEntry = (Map.Entry)((Iterator)localObject2).next();
      ((ArrayList)localObject1).add((String)localEntry.getKey() + "=" + (String)localEntry.getValue());
    }
    Collections.sort((List)localObject1, new Comparator()
    {
      public int compare(String paramAnonymousString1, String paramAnonymousString2)
      {
        return paramAnonymousString1.compareTo(paramAnonymousString2);
      }
    });
    localObject2 = new StringBuilder();
    int i = 0;
    if (i < ((ArrayList)localObject1).size())
    {
      if (i == 0) {
        ((StringBuilder)localObject2).append((String)((ArrayList)localObject1).get(i));
      }
      for (;;)
      {
        i += 1;
        break;
        ((StringBuilder)localObject2).append("&").append((String)((ArrayList)localObject1).get(i));
      }
    }
    localObject1 = ((StringBuilder)localObject2).toString();
    try
    {
      paramString = "POST&" + paramString + "&" + (String)localObject1;
      paramHashMap.put("snake_sign", new JustATest().getATestString(SkApplication.getInstance(), paramString));
      return;
    }
    catch (Exception paramString)
    {
      paramString.printStackTrace();
    }
  }

其中代码并不全,不过Android 开发者来说,补全这两句代码还是不在话下。其中最主要的paramHashMap.put("snake_sign", new JustATest().getATestString(SkApplication.getInstance(), paramString));这就是核心所在,看看getAtestString是什么鬼?

public class JustATest
{
  static
  {
    System.loadLibrary("JustATest");
  }
  
  public native String getATestString(Object paramObject, String paramString);
}

原来是调用的c的方法,.so文件在lib文件下,选择汇编工具IDA Pro试试,无奈P都没看懂,因为我也不会c。。。那就用最笨的方法,模拟它干的事就行了。建个Module跑起来175237_mw6J_2438532.png

记得包名要和它的包名一样,其中so文件还关联了QiniuEtagUtil.calss中方法,所以COPY过来,代码补全

175344_5E2N_2438532.png

抓取自己的UID跑起来,再打开app刷新,数据已更新,大功告成。

112749_jVzf_2438532.png

175653_iCMl_2438532.png

抓包

Fiddler 工具大名鼎鼎,平时做接口调试都用的是他,fiddler 手机抓包的教程Google也是一大把。下面放几张步骤截图。

180249_HvNE_2438532.png

180333_LbSt_2438532.png

然后是手机

180724_NFbD_2438532.png

都设置好了,此时需要关闭一下Fiddler再打开就看到效果了。

刷分

按上面图片步骤设置好Fiddler,打开贪吃蛇大作战app,Fiddler拦截到贪吃蛇大作战的http请求

114522_ucuW_2438532.png

随便选中一个,右侧可以看到需要的参数114631_PCiM_2438532.png

再把整行数据复制,填写到snake app 中。

114827_Vrlj_2438532.png

最终效果如下,然后就可以愉快的刷分啦。

113706_jH6A_2438532.png

app 上传至蒲公英,或者扫描二维码下载。

19114146_MMd4.jpg

源码上传至github

转载于:https://my.oschina.net/u/2438532/blog/790510

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值