首页
社区
课程
招聘
[原创]第一次接触APK[破解纪实]
发表于: 2014-11-22 19:18 7668

[原创]第一次接触APK[破解纪实]

2014-11-22 19:18
7668
前言
昨天刚把公司任务弄得差不多。同事想学粤语,下了一款XX粤语手机APP,让我帮他弄下。之前也没接触过APK,这次就当学习好了。
先下个JDK装好  再把Android SDK NDK统统装好,配置好环境变量,下载好需要的包,开搞。为了学习移动端的安全知识,买了一台安卓系统的手机作为一个测试环境。

1.下载下来APK解包
百度一下APK,11月20号还更新了。作者还挺勤快嘛。把APK下载下来,先解压看看里面是什么。发现里面的东西打不开~应该是要解包。从网上找了一下,有个apktool的还是很nice的,用apktool解包后如图:

2.再把程序安好,看看它里面到底是卖的什么药->是个什么样的注册方法

从以上两张图,可以知道明白了。
1>爆破。根据功能的需求一个地方一个地方的找,找到后再一一修改,但这显然不是最好的方法,繁琐而且不完美。
2>从积分入手。
(1)此软件的积分可以支付宝购买
(2)下载它推荐的“垃圾应用程序”
(3)帮他宣传。微博分享等等。
当然可以从这3方面的任何一方面入手,我认为都可以达到需要的刷积分的效果。
我的第一思路就是找到这个积分变量,并修改它。如果能成功,这样的破解就会是很完美的破解了。

3.定位
找字符串试试,到\res\values里面的String.xml里面看了一圈。

这个获取积分成功是不是很诱人呢?
打开Public.xml。找了对应的ID

0x7f060010。
OK,接下来我们在smali文件夹里搜索这个的引用。
发现了一个文件引用它  位置在:smali\com\movesky\a\c.smali

4.分析代码

由于对smali代码接触得不多,打开之后,发现完全看不懂。怎么办?没事~本来就是需要今后的学习。~既然看不懂smali代码,那我们为什么不可以换个代码看呢?
那就用Java decompiler吧  Java我总能看懂吧~

先看看C类里写的是什么东西。

一共有2个函数,成功的函数代码如下:
public final void onSuccess(long paramLong)
  {
    String str = Integer.toString((int)(paramLong / 1L)); //取相应任务的分值
    Log.i("ZRD", "奖励积分:" + str);///刷新分值显示
    Toast.makeText(this.d, this.d.getString(2131099664) + str, 0).show();//显示获取积分成功
    K.a(this.d, new Handler(), str, "dianjing", "Add");//把积分数据更新下
  }
}

OK.显然按照我的思路来,最后一句代码当然更吸引我。那继续追踪K类:
public final class K
{
  private static List<NameValuePair> bb;

  private static JSONArray a(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5)
  {
    JSONArray localJSONArray = new JSONArray();
    JSONObject localJSONObject = new JSONObject();
    try
    {
      localJSONObject.put("Fld_Points", paramString1);
      localJSONObject.put("Fld_Action", paramString2);
      localJSONObject.put("Fld_State", paramString3);
      localJSONObject.put("Fld_Source", paramString4);
      localJSONObject.put("Fld_Note", paramString5);
      localJSONArray.put(localJSONObject);
      return localJSONArray;
    }
    catch (JSONException localJSONException)
    {
      while (true)
      {
        localJSONException.printStackTrace();
        ZrdCommon.ZrdLog.Log("Err=" + localJSONException.getMessage());
        localJSONObject = new JSONObject();
      }
    }
  }

  public static void a(Context paramContext, Handler paramHandler)
  {
    a(paramContext, new JSONArray(), paramHandler);
  }
public static void a(Context paramContext, Handler paramHandler, String paramString1, String paramString2, String paramString3)
  {
    a(paramContext, a(paramString1, "1", "1", paramString2, paramString3), paramHandler);
  }

  public static void a(Context paramContext, Handler paramHandler, String paramString1, String paramString2, String paramString3, String paramString4, String paramString5)
  {
    a(paramContext, a(paramString1, paramString2, paramString3, paramString4, paramString5), paramHandler);
  }

  private static void a(Context paramContext, JSONArray paramJSONArray, Handler paramHandler)
  {
    Activity localActivity = (Activity)paramContext;
    ArrayList localArrayList = new ArrayList();
    bb = localArrayList;
    localArrayList.add(new BasicNameValuePair("_VKey", AppJNI.i()));
    bb.add(new BasicNameValuePair("_MaxID", "0"));
    bb.add(new BasicNameValuePair("_DevID", n.a(localActivity)));
    bb.add(new BasicNameValuePair("_BundleID", paramContext.getPackageName()));
    bb.add(newBasicNameValuePair("_BundleVersion", paramContext.getString(2131099661)));
    bb.add(new BasicNameValuePair("_ChannelID", paramContext.getString(2131099662)));
    bb.add(new BasicNameValuePair("_PointsDetail", paramJSONArray.toString()));
    ZrdCommon.ZrdLog.Log("YSpoints Updata PointsDetail=" + paramJSONArray.toString());
    new L(paramContext, paramHandler).start();
  }
}

找到对应的函数,一共套了几层,稍微需要一点耐心,但并没有难度。上面的几个a函数都是对传进来参数的一切处理,都是字符串游戏。对上述代码分析后可得 private static void a(Context paramContext, JSONArray paramJSONArray, Handler paramHandler)这个函数是最关键的函数。
分析paramJSONArray里的内容如下:
["Fld_Points":str,                                                  //这里的str就是完成对应任务的分数.toString()
"Fld_Action":"1",
"Fld_State":"1",
"Fld_Source":"dianjing",                               
"Fld_Note":"Add"]                                        //方法为Add

跟到这个时候发现这个函数的作用是客户端给服务器提交参数的函数。
悲剧了,分析了这么多~积分却不在本地。
于是这个时候可能又跳出有几种思路:
1>劫持这个变量
2>本地化,在本地完成任务达到免费使用
3>骗服务器
又去String.xml翻了翻。发现一个新的东西

URLPoints,那就是服务器存放APP积分的地址了。
进入如下:

看到SumPoints 居然是个负的。
那我们可不可以不让它访问服务器而把那个变量改成自己想要的值呢?我觉得这是一种可行的思路。
因为第一次弄,思路也是天马行空。当时想,
他这种访问服务器获取积分的方法,地址都是一个PHP文件。那肯定要验证机器码的,然后我把手机机器码屏蔽掉了,发现积分溢出了。贴出两张图为证:

这样这个程序也算是完美破解了~
第一次接触apk破解,难免有理解得不对的地方和弯路,希望大家能多多指正,多多交流方法,希望把不足之处告诉我,共同进步。
                                                                                    2014.11.22
                                                                                    By Eric

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
很详细的教程,感谢分享
2014-11-22 20:52
0
雪    币: 2950
活跃值: (1793)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
3
不错,手机软件似乎比PC软件更有吸引力,手机普及太强悍了
2014-11-22 21:18
0
雪    币: 141
活跃值: (54)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
[QUOTE='wofan[OCN];1332755']不错,手机软件似乎比PC软件更有吸引力,手机普及太强悍了[/QUOTE]

说得很对啊 ,以后移动端会超普及~现在得赶快入手,到时候apk出了很多加密方法再入手又会比较麻烦了。
2014-11-22 21:34
0
游客
登录 | 注册 方可回帖
返回
//