随便谈谈Android的逆向工程

Android_Robots_Banner
Standard

假期里闲来无事,就开始倒腾。

所谓(软件的)逆向工程,听起来很貌似高端,它实际上就是根据软件运行后的表现进行逆向分析和研究,从而推理出该软件的处理逻辑、功能结构等要素,以制作出功能相近,但又不完全一样的产品。它的目的、也是难点在于,在不能轻易获得源代码的情况下下,直接从对软件的分析,推导出它的设计原理。

为了让逆向工程的结果看起来有点用,我选了《么么答》这款应用作为“实验对象”。

《么么答》是人人网旗下的一款社交教育类问答游戏,拥有海量题库。可以与好友对战答题或是进入天梯PK。

我猜应该有很多人玩得比我还熟,就不多作介绍了。


初体验

逆向工程的第一步是要“使用”这款软件,熟悉它的流程。把所有能点的按钮啊、菜单啊都点一遍,知道它有哪些功能。当然,重点就是测试答题的过程了。稍试几次,便容易发现一个清晰的答题的流程:

  1. 选择分类
  2. 读取题目
  3. 互相答题
  4. 最终结果

对一般用户来说,所能体验到的东西也就这些了。但对于逆向工程来说,还远远不够,要从这个看似简单的流程中读到更多信息。


细分析

我们要思考一些问题,或是说收集一些信息。有些问题是很显然的,有些则需要一些推理才能得出结论。

1. 这些题目存储在哪里?是下载应用时就附带题库的吗?

答:题目一般会被编有一个唯一的序号,以作区分。所以在下载应用时就附带题库也并非不可。但要注意到其包含有提交问题的功能。既然题库会被不停地更新,那本地放题库就没有意义了。这些题目当然存在于官方的服务器上,而且极有可能的是,没有本地题库。

2. 第一步选择完分类后,题目是从哪里读取的呢?

答:是从《么么答》的官方服务器上读取的。

3. 第二步读取的题目包含答案吗?

答:可以很明确地给出答案,包括。如此确信是因为一个细节:当你选择完一个答案后,应用会立刻给出对或错的反馈。如果第二步读取的题目不包含答案,那么在用户选择选项后便存在向服务器询问答案是否正确的网络连接,这是需要时间的。但实际情况是,几乎是在指尖触碰选项的一刹那,就给出了答案,没有任何延时(有时反而有加分动画的延迟)。

这样设计的初衷应该是优化用户体验,我猜。设计本身没问题,但却留下了一些问题,先按下不表,等把信息收集完再分析。

4. 第三步互相答题的传输方式是什么?

答:我曾想过它会不会用点对点(P2P)方式传输,后来在一大堆技术论证下发现是不可能的。所以就只有以服务器为主机来通信了。


至此,信息基本收集全了。我们反向推理出了答题过程内部运作的流程,包括通信的时间、内容和方式。尽管至此还不知道软件用的是什么通信协议、什么接口,但是却知道它会在什么时间传输什么内容,这真是一件神奇的事,隐隐有种“未卜先知”的感觉。要注意,现在还没有开始进行任何实际的逆向工程操作哦!一切只是在脑子里想想而已。磨刀不误砍柴工嘛!╭(′▽`)╯


正片

下面要做的事看起来可能有点疯狂。既然已经确信它会在答题的第二步传输题目和答案,那能否在看到问题前就知道答案呢

谁知道呢?总得试试看吧!


首先,我们先得想办法监控到《么么答》的网络流量,方法很多,这里就不具体介绍了。

在监控到网络流量后,记录下一到两次正常答题的过程中产生的所有网络流量,并进行分析。

功夫不负有心人,在经历了漫长的10分钟中对数据包的分析后,终于找到了它的庐山真面目。

Pcap Dump

Pcap Dump

注意到第#1160帧,收到了服务器发来的疑似问题与答案的数据包,信息被包裹在一个标签下。由于数据量很大,数据包被拆成了两份(#1160和#1161),并且在第#1167和#1168帧处得到了确认。这些信息都可以在上图中观察到。

看不全的是数据包的结构,为了方便起见,直接将#1160和#1161帧传输的数据译码后贴出如下:

message={"channelId":251957697,"cid":525420944,"msgId":4,"subjectGroup":[
{"answer":2,"contributer":0,"contributerName":"","imageUrl":"","options":["穿越火线","英雄联盟","CS","魔兽"],"subjectId":282743,"title":"总是被称为撸主的孩纸玩什么游戏?","topicId":160001,"topicName":"应用宝应用题大赛"},
{"answer":3,"contributer":0,"contributerName":"","imageUrl":"","options":["6人","9人","8人","7人"],"subjectId":281865,"title":"唱吧的频道共有6人,后来又进来2人,目前频道共有多少人?","topicId":160001,"topicName":"应用宝应用题大赛"},
{"answer":1,"contributer":0,"contributerName":"","imageUrl":"","options":["4","5","7","6"],"subjectId":281561,"title":"有道词典支持几种语言与中文互译?","topicId":160001,"topicName":"应用宝应用题大赛"},
{"answer":4,"contributer":0,"contributerName":"","imageUrl":"","options":["卡牌类","冒险类","射击类","塔防类"],"subjectId":281843,"title":"舰队大作战2是一款什么类型的游戏?","topicId":160001,"topicName":"应用宝应用题大赛"},
{"answer":2,"contributer":0,"contributerName":"","imageUrl":"","options":["迅雷看看","爱奇艺","暴风影音","快播"],"subjectId":282827,"title":"高科技少女喵是在哪个平台上独播的?","topicId":160001,"topicName":"应用宝应用题大赛"},
{"answer":4,"contributer":0,"contributerName":"","imageUrl":"","options":["黄继新","李岷","刘成城","嵇晓华"],"subjectId":283031,"title":"果壳网的创始人是?","topicId":160001,"topicName":"应用宝应用题大赛"},
{"answer":3,"contributer":0,"contributerName":"","imageUrl":"","options":["全民农场","天天富翁","易信","节奏大师"],"subjectId":283231,"title":"以下哪款应用非腾讯旗下?","topicId":160001,"topicName":"应用宝应用题大赛"}
],"sync":true,"type":202}

啊哈,你没有看错!这是真的!这信息挺直白的,不用机翻,肉眼就能看懂它在讲什么了。(看不懂中文的面壁去!)不过貌似打了好多好多好多的广告


至此,通过分析网络流量,便“马后炮”般的获得了题目和答案。同时,也用实际结果验证了先前的推理过程——它确实是在题目传输过程中包括了答案。

---下面是私货---

那这又意味着什么呢?

意味着信息不安全了?好像不是。意味着可以提前看到答案?好像是这个意思。意味着别人可以偷听数据?Yep!(这才是我真正想说的。)设想你的网络流量被监听了,再设想你不是简单地只是在玩这一款游戏,那会发生什么。那些信息就这样毫无加密地赤裸裸地呈现在别人眼前。那种“人为刀俎,我为鱼肉”的情形,并非是不可能发生的。

---私货结束---


预知梦

“观今夜之星象,知天下之大事。” 此并非易事,也非难于上青天。

当然,真要做这种事的话,只得让 Python 出马了。

为啥要用 Python 呢?很关键的一个因素就是方便,它有一个相当全的库,能满足各种奇葩需求。就比如现在这种监听网络流量的事,Python 也有对应的封装好的包,直接拿来用就好!(我才不会告诉你们最痛苦的是装包的过程呢!)

因为我十分确信,就算我把代码放出来,先是90%的不会运行,其次是90%的人运行不了,所以就算了吧。o(-"-;)

那就贴一张运行时截图吧:

memeda_question_sniff

运行时截图,信不信由你

如此剧透真的好么!我《绝命毒师》还没看完呢摔!

郑重申明:本文中的内容仅供技术交流,各位看看就好,千万不要拿它来干坏事,否则后果自负

Ps:其实想吐槽一下写这个客户端的人的水平的,后来槽点太多以至于无从说起了 (ーー゛)


总结

本文以某一知名应用为例,简要地讲了逆向工程的一些思路和流程。由于某些原因,文中省略了一些关键的技术与实施方法,着重强调思路。重要的是解决一个问题时所用的思考方法,用了哪些技术是次要的。看得懂的自然知道我在说什么,看不懂的大概囫囵吞枣就行了,不必较真。

欢迎就任何你觉着合理的问题进行交流!

如果想看的人多的话,我就写个续集,么么哒 ╰(°▽°)╯