微信在7.0版本发布之后,我们可以看到有很大的改变,首先是UI上的变化,其次就是即刻视频,因为2018年是短视频火爆的一年,有抖音的强悍吸粉,连微信也开始担心社交地位以及用户的时间被强占,所以在各种屏蔽之后无果,开始尝试自己的一个社交+短视频的方式,这就是我们看到的即刻视频,我们用过即刻视频都知道,视频现在只支持观看却不支持下载,但是有时候我们看到好友发布了一个搞笑的视频却不能保存到本地也是挺难受的,所以这里我们就开发一款插件可以支持下载。
下面就开始我们的分析,当然本文以及以后的插件开发我们都将用一种全新的分析方式找到hook点,这也是本文的一个新知识点和技能,大家不要关心插件的结果,看中的是文章的过程学习技术。
这里可以看到我们story发布页面其实还是很简单的,可以添加表情文字,配乐以及位置信息,当然我们后续还有一些插件比如可以添加本地自己喜欢的配乐,然后就开始发布:
我们长按视频发现只有删除选项,但是有时候我们看到其他人的视频我们想下载怎么办呢?到这里就是我们的诉求了,我们本文的目的就是添加一个下载插件,首先我们用UI工具获取当前页面的元素信息:
看到我们找到这个删除的选项了,看到id是ki,这时候我们会反编译微信之后,以往的操作是去public.xml中查找这个id,然后去Jadx打开微信进行查找代码,但是现在不这么做了,因为我们发现微信在后续的版本的dex非常大,用Jadx打开非常卡,所以我们需要分开dex进行打开操作,但是dex太多打开也很费劲,所以我们这里直接借助find命令进行操作,当然Windows中的是findstr命令。
首先我们还是去values/public.xml中找到这个id值,然后进行全局搜索:
看到这个16进制的值,进行搜索即可:
这里的命令非常重要,后续我们都会用这个命令:find . |xargs grep -ri "搜索内容" 这样我们就把这个id找到了对应的smali代码中了,不过这里还是有很多个,不过我们看到每个搜索结果前缀都可以看到dex,这样就没必要每个dex打开挨个搜索了,这样我们就可以直接到指定的dex中找了,不过这里发现好像很多而且没有我们想要的,这时候就需要对即可视频的了解了,其实这类的社交发送视频的可能都有一个关键字就是:story,比如Instagram的快拍功能也是叫做Story功能。这时候我们在用grep进行过滤一下:
这样我们就定位到应该是第8个dex文件中了,这时候打开即可,不过这里不打开了,因为到这里其实对于我们这次操作没多大作用,但是为什么要说这个呢?因为后面的查找技术都是基于这个find命令的,所以以后大家不要在挨个打开dex文件查找了,效率很低,下面继续来说本文的第二个技术点就是快速的找到我们想要的东西。
我们知道应用为了开发调试方便,可能会在代码中添加日志信息,但是因为一些特殊原因可能日志有一个开关,可以控制debug包可以查看日志,release不可以,不过有的公司为了安全会用脚本把代码中所有的系统打印日志代码全部干掉,因为日志信息可以很快的定位到我们想要的东西,我们可以随便打开微信的一个dex文件,查看他的日志封装类:
看到微信的日志类是ab,因为这个日志应该有很多打印的方法,所以需要找到这个类的定义地方,这时候我们就可以用上面的find命令进行查找了:
注意:因为find搜索之后会有很多信息,而我们其实就是想找到这个类,所以最好在做一层过滤,一般都是类名.smali即可,这样很快就定位到指定的dex文件了,这个方法在后面非常常用。
我们这里直接搜索这个类,当然应该搜索结果很多,可以再加一层过滤,就是类的后缀名即可,这样就很快的定位到这个类是在第一个dex中,直接用Jadx打开即可:
这里我们直接hook这些类,然后把参数打印出来就可以通过日志定位我们想要的东西了:
不过到现在我们还没有说我们想要啥呢?首先我们要是下载这个视频,肯定需要这个视频的地址,然后就是添加一个下载点击的入口:
我们打开一个即可视频就发现了,这里的日志输出发现了一个storyitem的信息,里面的确包括了下载地址,可以选择多个即可视频来回切换就发吸纳了这个选中的日志信息,然后继续去搜索这个日志信息:
日志可能有点多不过没关系,这个我们可能需要通过判断,因为是字符串信息,所以查找就比较方便,这样我们就看到大致是在第10个dex中,然后找到这个类:
当我们每次选择一个即可视频的时候都有这个日志,而且看到item关键字,通过日志我们发现,我们需要获取那个qTS变量,但是看到前面有很多的方法调用,我们可以依次查找变量的调用地方也可以,我们查看rhg变量类型:
因为多个即可视频是可以左右滑动切换的,这里看到是用了RecyclerView实现的,所以通过上面的那个一连串的调用可以发现qTS变量应该保存在itemView中的,而且看到下面的一行代码发现:
StoryGalleryItemView可以直接设置Video的信息,所以猜想在这个View中应该保留了视频的item信息,当然如果做过Android应用开发,这个也是很容易想到的,这样就简单了,我们查看这个类,当然我们发现这个类不在这个dex中,但是有没发现import这个类,那说明这个类是和l这个类在同一个包下面的,那直接搜索即可:
这里发现这个类是在第6个dex中:
这里我们看到的qTS变量了,继续搜索这个类型:
这里搜到这个类是在第8个dex中:
这里看到toString方法的打印信息,我们想要的url信息就是qTY.Url中,那么到这里我们就获取到的即刻视频的url信息了,这时候只需要hook加上反射即刻:
运行这个模块,然后选择一个即可视频查看日志信息:
有了下载地址还是不够的,我们还需要一个下载的入口,我们通过查看别人的即刻视频发现,没有多余的操作入口,所以这时候我们要是去添加可能比较麻烦,当然有的同学第一个想法就是我们在上面不是拿到了RecyclerView和ItemView的吗?那么我们现在只要给这个View添加点击事件不就好了吗?的确这个思路没毛病,不过我测试了发现这个点击事件不会走,猜想他可能做了点击触摸事件的处理,这时候没关系,我们继续通过日志找入口,比如这里我们点击一下即可视频页面,发现了这些日志:
其中最重要的就是downX,dispatchTouchEvent信息,这个做过应用开发都知道点击事件应该是他们内部做处理了,我们查看这个日志在哪里即可:
通过查看发现很多信息,但是在其中看见了l这个类信息,进入查看看到这个方法了,看到有点击的x,y坐标信息,那么如何在这个方法中做点击事件呢?这个做过应用开发处理Touch和Click事件冲突的同学都知道,可以在Touch方法中做到点击事件的,就是通过判断down和up的时间间隔不要超过一定时间一般是200ms就认为是点击事件:
然后我们运行打印日志信息查看:
这里看到的确走到了点击事件,那么接下来也简单了,我们在点击之后就弹出一个下载的对话框吧,展示对话框我们知道需要依赖于当前页面的Activity,这个很简单,我们dump出当前页面的activity信息,然后hook他的onResume方法获取全局变量即可:
直接hook页面的onResume方法:
有了变量之后展示对话框就简单了:
然后在对话框中添加一个点击事件即可,因为有了视频的地址,那么下载就简单多了:
到这里我们就成功的把插件完成了,看到本文和之前的写插件的分析过程是不是不太一样,的确这个以后都会采用这种高效的方式。
1、本文不在按照之前的那种逐个打开dex文件挨个搜索了,而是采用高效的有目的的定位搜索方法,当然我们知道微信的dex文件很多,如果应用的dex文件很多的话,可以采用这种搜索方式非常高效。
2、我们知道之前也说过app逆向的入口也就那么几个,查看页面元素信息,抓包查看URL,查看日志信息,而一般大型app都会对日志进行封装一层,而且通过本文发现,通过日志定位逆向入口是非常便捷的,只需要找到日志的封装类,然后hook之后打印参数即可,不费吹灰之力即可找到入口信息。
3、借助Mac的find命令,代替以往的Jadx打开多个dex文件依次查找的低效率方式,看到本文就发现了几乎都是靠这个命令进行定向查找指定类代码信息,当然这个也是被逼无奈,因为微信7.0之后的dex文件特别多,逐个查找太费劲了,而且我的电脑直接打开Jadx打开微信几乎都是卡死的。所以无奈想到这种方式。其实发现还是非常好用的,而且后面的插件都采用这种方式处理。
本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系,本文涉及到的代码项目可以去编码美丽小密圈自取,欢迎加入小密圈一起学习探讨技术
到这里我们就把即可视频的下载插件开发完了,当然这个不是结束而只是开始,后续我们会继续开发很多个插件,当然在说明一点就是开发插件不要在乎结果,大家一定要看过程,我想传播的是逆向技巧而不是一个单纯的插件。