jiangwei212 发表于 2019-4-15 08:28

Android微信即刻视频下载器插件开发过程原理详解

本帖最后由 jiangwei212 于 2019-4-15 22:54 编辑

一、前言分析
微信在7.0版本发布之后,我们可以看到有很大的改变,首先是UI上的变化,其次就是即刻视频,因为2018年是短视频火爆的一年,有抖音的强悍吸粉,连微信也开始担心社交地位以及用户的时间被强占,所以在各种屏蔽之后无果,开始尝试自己的一个社交+短视频的方式,这就是我们看到的即刻视频,我们用过即刻视频都知道,视频现在只支持观看却不支持下载,但是有时候我们看到好友发布了一个搞笑的视频却不能保存到本地也是挺难受的,所以这里我们就开发一款插件可以支持下载。

二、逆向分析
下面就开始我们的分析,当然本文以及以后的插件开发我们都将用一种全新的分析方式找到hook点,这也是本文的一个新知识点和技能,大家不要关心插件的结果,看中的是文章的过程学习技术。
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/01.png​
这里可以看到我们story发布页面其实还是很简单的,可以添加表情文字,配乐以及位置信息,当然我们后续还有一些插件比如可以添加本地自己喜欢的配乐,然后就开始发布:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/02.png
我们长按视频发现只有删除选项,但是有时候我们看到其他人的视频我们想下载怎么办呢?到这里就是我们的诉求了,我们本文的目的就是添加一个下载插件,首先我们用UI工具获取当前页面的元素信息:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/03.png
看到我们找到这个删除的选项了,看到id是ki,这时候我们会反编译微信之后,以往的操作是去public.xml中查找这个id,然后去Jadx打开微信进行查找代码,但是现在不这么做了,因为我们发现微信在后续的版本的dex非常大,用Jadx打开非常卡,所以我们需要分开dex进行打开操作,但是dex太多打开也很费劲,所以我们这里直接借助find命令进行操作,当然Windows中的是findstr命令。

首先我们还是去values/public.xml中找到这个id值,然后进行全局搜索:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/04.png
看到这个16进制的值,进行搜索即可:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/05.png
这里的命令非常重要,后续我们都会用这个命令:find . |xargs grep -ri "搜索内容" 这样我们就把这个id找到了对应的smali代码中了,不过这里还是有很多个,不过我们看到每个搜索结果前缀都可以看到dex,这样就没必要每个dex打开挨个搜索了,这样我们就可以直接到指定的dex中找了,不过这里发现好像很多而且没有我们想要的,这时候就需要对即可视频的了解了,其实这类的社交发送视频的可能都有一个关键字就是:story,比如Instagram的快拍功能也是叫做Story功能。这时候我们在用grep进行过滤一下:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/06.png
这样我们就定位到应该是第8个dex文件中了,这时候打开即可,不过这里不打开了,因为到这里其实对于我们这次操作没多大作用,但是为什么要说这个呢?因为后面的查找技术都是基于这个find命令的,所以以后大家不要在挨个打开dex文件查找了,效率很低,下面继续来说本文的第二个技术点就是快速的找到我们想要的东西。

我们知道应用为了开发调试方便,可能会在代码中添加日志信息,但是因为一些特殊原因可能日志有一个开关,可以控制debug包可以查看日志,release不可以,不过有的公司为了安全会用脚本把代码中所有的系统打印日志代码全部干掉,因为日志信息可以很快的定位到我们想要的东西,我们可以随便打开微信的一个dex文件,查看他的日志封装类:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/07.png
看到微信的日志类是ab,因为这个日志应该有很多打印的方法,所以需要找到这个类的定义地方,这时候我们就可以用上面的find命令进行查找了:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/08.png
注意:因为find搜索之后会有很多信息,而我们其实就是想找到这个类,所以最好在做一层过滤,一般都是类名.smali即可,这样很快就定位到指定的dex文件了,这个方法在后面非常常用。

我们这里直接搜索这个类,当然应该搜索结果很多,可以再加一层过滤,就是类的后缀名即可,这样就很快的定位到这个类是在第一个dex中,直接用Jadx打开即可:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/09.png
这里我们直接hook这些类,然后把参数打印出来就可以通过日志定位我们想要的东西了:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/10.png
不过到现在我们还没有说我们想要啥呢?首先我们要是下载这个视频,肯定需要这个视频的地址,然后就是添加一个下载点击的入口:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/11.png
我们打开一个即可视频就发现了,这里的日志输出发现了一个storyitem的信息,里面的确包括了下载地址,可以选择多个即可视频来回切换就发吸纳了这个选中的日志信息,然后继续去搜索这个日志信息:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/12.png
日志可能有点多不过没关系,这个我们可能需要通过判断,因为是字符串信息,所以查找就比较方便,这样我们就看到大致是在第10个dex中,然后找到这个类:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/13.png​
当我们每次选择一个即可视频的时候都有这个日志,而且看到item关键字,通过日志我们发现,我们需要获取那个qTS变量,但是看到前面有很多的方法调用,我们可以依次查找变量的调用地方也可以,我们查看rhg变量类型:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/14.png
因为多个即可视频是可以左右滑动切换的,这里看到是用了RecyclerView实现的,所以通过上面的那个一连串的调用可以发现qTS变量应该保存在itemView中的,而且看到下面的一行代码发现:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/15.png
StoryGalleryItemView可以直接设置Video的信息,所以猜想在这个View中应该保留了视频的item信息,当然如果做过Android应用开发,这个也是很容易想到的,这样就简单了,我们查看这个类,当然我们发现这个类不在这个dex中,但是有没发现import这个类,那说明这个类是和l这个类在同一个包下面的,那直接搜索即可:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/16.png
这里发现这个类是在第6个dex中:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/17.png
这里我们看到的qTS变量了,继续搜索这个类型:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/18.png
这里搜到这个类是在第8个dex中:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/19.png
这里看到toString方法的打印信息,我们想要的url信息就是qTY.Url中,那么到这里我们就获取到的即刻视频的url信息了,这时候只需要hook加上反射即刻:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/20.png
运行这个模块,然后选择一个即可视频查看日志信息:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/21.png
有了下载地址还是不够的,我们还需要一个下载的入口,我们通过查看别人的即刻视频发现,没有多余的操作入口,所以这时候我们要是去添加可能比较麻烦,当然有的同学第一个想法就是我们在上面不是拿到了RecyclerView和ItemView的吗?那么我们现在只要给这个View添加点击事件不就好了吗?的确这个思路没毛病,不过我测试了发现这个点击事件不会走,猜想他可能做了点击触摸事件的处理,这时候没关系,我们继续通过日志找入口,比如这里我们点击一下即可视频页面,发现了这些日志:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/22.png
其中最重要的就是downX,dispatchTouchEvent信息,这个做过应用开发都知道点击事件应该是他们内部做处理了,我们查看这个日志在哪里即可:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/23.png
通过查看发现很多信息,但是在其中看见了l这个类信息,进入查看看到这个方法了,看到有点击的x,y坐标信息,那么如何在这个方法中做点击事件呢?这个做过应用开发处理Touch和Click事件冲突的同学都知道,可以在Touch方法中做到点击事件的,就是通过判断down和up的时间间隔不要超过一定时间一般是200ms就认为是点击事件:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/24.png
然后我们运行打印日志信息查看:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/25.png
这里看到的确走到了点击事件,那么接下来也简单了,我们在点击之后就弹出一个下载的对话框吧,展示对话框我们知道需要依赖于当前页面的Activity,这个很简单,我们dump出当前页面的activity信息,然后hook他的onResume方法获取全局变量即可:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/26.png
直接hook页面的onResume方法:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/27.png
有了变量之后展示对话框就简单了:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/28.png
然后在对话框中添加一个点击事件即可,因为有了视频的地址,那么下载就简单多了:
https://fourbrother-img-1252178963.cos.ap-beijing.myqcloud.com/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1Story%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%99%A8/GIF.gif
到这里我们就成功的把插件完成了,看到本文和之前的写插件的分析过程是不是不太一样,的确这个以后都会采用这种高效的方式。

三、技术总结
1、本文不在按照之前的那种逐个打开dex文件挨个搜索了,而是采用高效的有目的的定位搜索方法,当然我们知道微信的dex文件很多,如果应用的dex文件很多的话,可以采用这种搜索方式非常高效。
2、我们知道之前也说过app逆向的入口也就那么几个,查看页面元素信息,抓包查看URL,查看日志信息,而一般大型app都会对日志进行封装一层,而且通过本文发现,通过日志定位逆向入口是非常便捷的,只需要找到日志的封装类,然后hook之后打印参数即可,不费吹灰之力即可找到入口信息。
3、借助Mac的find命令,代替以往的Jadx打开多个dex文件依次查找的低效率方式,看到本文就发现了几乎都是靠这个命令进行定向查找指定类代码信息,当然这个也是被逼无奈,因为微信7.0之后的dex文件特别多,逐个查找太费劲了,而且我的电脑直接打开Jadx打开微信几乎都是卡死的。所以无奈想到这种方式。其实发现还是非常好用的,而且后面的插件都采用这种方式处理。


四、总结
到这里我们就把即可视频的下载插件开发完了,当然这个不是结束而只是开始,后续我们会继续开发很多个插件,当然在说明一点就是开发插件不要在乎结果,大家一定要看过程,我想传播的是逆向技巧而不是一个单纯的插件。欢迎购买本人逆向大黄书「Android应用安全防护和逆向分析」





bachelor66 发表于 2019-4-15 09:36

图片一直转圈圈啊?                        

52002501 发表于 2019-4-25 10:18

好像我又有个回复给吃掉了,热心顶贴也算违规了?这个帖子我可是和认真的看完了。我可是学会了findStr的人。不能再吃我的回复了。

mosou 发表于 2019-4-15 08:37

前排支持4哥,一向干货

az12az 发表于 2019-4-15 08:42

支持技术文章。

ilhuyi 发表于 2019-4-15 09:00

写的很详细啊,感谢

无痕软件 发表于 2019-4-15 09:03

为啥我都是图片圈圈

chen136261! 发表于 2019-4-15 09:52

66666666666666666666

jason1204 发表于 2019-4-15 10:43

图片打不开啊

Galaxy丿天下 发表于 2019-4-15 10:56

我的网不好?图片在路途中丢失了?

xixicoco 发表于 2019-4-15 12:22

四哥出品,必属精品,爱你哟
页: [1] 2 3 4 5 6 7 8 9
查看完整版本: Android微信即刻视频下载器插件开发过程原理详解