1.胡乱分析第一波
微信消息从发送到撤回的几步
先不具体去看源码,如果是让你来做这个消息撤回,流程会是怎样? 首先,信息肯定是持久化到本地的,一般会保存在数据库里,不然怎么每次打开。
撤回操作 -> 根据某一个标记检索数据库里的记录 -> 删除记录 -> 更新页面 -> 发送信息到服务器更新其他用户的撤回状态。
Maybe是这样,接着就开始跟代码了,依旧是捞比的逆向套路:方法跟踪 + 反编译源码 + 日志定位。 从点下撤销开始跟踪,直到页面显示撤销成功~,入手关键词SQLite,然后依次涉及到这几个类:
com.tencent.wcdb.database.SQLiteCursor com.tencent.wcdb.database.SQLiteQuery com.tencent.wcdb.database.SQLiteSession com.tencent.wcdb.database.SQLiteConnection com.tencent.wcdb.database.SQLiteDatabase com.tencent.wcdb.database.SQLiteProgram com.tencent.wcdb.database.SQLiteStatement com.tencent.wcdb.database.SQLiteQueryBuilder
接下来就要一个个看这个类大概是干嘛的了,用AS打开反编译的项目,然后打开这些类,左侧选择
一个个结构看,限于篇幅这里就不一一列举了,最终定位类应该是SQLiteDatabase,它的结构里看到了这些方法:
接着就细化关键词再搜索,进行方法跟踪。
进去代码看下这个update方法~
好吧,update调用的是**updateWithOnConflict()**方法,把参数打印出来看看?
运行结果发现每接受到一条信息都会触发这个方法,连公众号信息也会调用。
可以,那么分别来看看自己发信息撤回和别人发信息撤回 的两种情况:
不难发现,第一个参数应该是一个代表信息类型的东西,普通信息是rconversation,而撤回信息类型是message,然后是第二个参数,类型是ContentValue,这个类用于存取键值对的数据,每个键值对表示一列的列名和该列的数据,撤回类型的信息除了上面的content外还有后面一块:
我们先要明确防止撤回的是别人发的信息而不是自己的,所以先要过滤掉自己的,对比两种情况得出这样的结论:
-> 判断第一个参数是否为message -> 获取第二个参数中的type判断是否等于10000(自己撤回是10002)
修改下程序,只处理别人发的信息的情况,打Log验证下,
看Log却意外发现了一个问题:
是的,多了个你撤回了一条信息,出现这条信息的原因是微信整了个比较贴心的功能:
用户撤回信息的原因可能是编辑内容错误,在五分钟以内,用户点击可以通过点击重新编辑, 获得撤回的文本信息,然后进行重新编辑,五分钟过后就会变成你撤回了一条消息。
所以判断条件还要加上这个过滤条件,所以代码就变成:
继续看Log: