一、知识回顾
最近有人找我弄微信数据库解密的东西,其实这个现在网上都公开了,我在很早之前就静态分析过微信数据库加密算法,不了解的同学可以查看这里:Android中静态方式破解微信数据库加密密码,所以现在有人找我的话我都会告诉他们这个内容,微信数据库加密的密码很简单就是:MD5(IMEI+UIN).Substring(0, 7).toLower;设备的imei和微信登录账号后的唯一表示uin值拼接然后计算MD5值,取前7位在变成小写字母即可。这个我在那篇文章最后也说到了,这个加密算法不会变化的,因为维系为了兼容以前版本,如果数据库加密算法变动,那么老版本的用户升级到新版本,老版本的数据库解密就会失败,也就是用户看不到以前的消息内容了,这个用户会疯的,所以微信即使知道了这个算法被破解了,他也是没办法升级的,所以现在不会变,以后也不会变的。但是比较奇葩的是他按照我的文章操作计算出来的密码还是不可以。所以我就让他把我的数据库文件传给我我来解密,中间其实我遇到了问题最后才知道被微信转码坑了,因为他微信把IMEI和UIN传递给我了,结果我直接复制计算MD5是错的,最后才知道微信消息中有转码的。
二、获取解密密码
所以开始就计算错误,他一度怀疑微信的加密算法是不是变化了,但是这一点我还是坚信微信不可能换加密算法的,这个原因我之前也说了,对于微信来说几乎是不可能操作的。然后他就在网上搜找到一个收费的PC端工具,大致是这样的:
只需要选择微信的数据库目录MicroMsg即可,就可以识别出来用户,然后点击指定用户就可以查看对应的数据了,所以他这么一说我倒是有点怀疑我的方法了?因为毕竟他用这个工具解密是没有问题的。所以我就用这个工具查看了一下的确没问题,那么为什么这个工具可以解密成功呢?所以我就想探究这个工具的原理,但是我不会PC端的软件逆向,但是我们可以借助强大的逻辑排除法定位,你看这个工具是需要选择微信数据库目录的,也就是这样的格式:
我就好奇了,我们在之前的文章中了解到用忽的UIN是存储在xml中的,但是你看这个工具只要导入这个目录就可以解密,也就是说他能够拿到设备imei和uin值,所以我就怀疑他读取这个目录下的几个文件获取的,那么就一个一个排除,首先通过肉眼判断哪些文件肯定不是的,最后发现就这几个cfg文件打开是二进制文件,所以怀疑对象就在这几个文件了,因为文件不多,我们可以这么排除,就是通过逐一修改文件名,然后在用那个工具解密,如果提示错误了,那么就表示这个文件是关键的,通过最后排查,有两个文件不能修改,也就是上图中文件名后面没有11的两个,一个是systemInfo.cfg和CompatibleInfo.cfg了。那么这个文件是二进制文件,怎么解密呢?这个就简单了,直接用Jadx全局搜这两个文件:
运气很好,正好在第一个dex中就搜到了,点进去查看:
继续点进去查看:
到这里就看明白了,原来不是什么加密操作,而是序列化对象到文件中,那么想看这个文件的原始内容就简单了,我们去写一个Java程序把文件中的内容读取出来是Map结果,然后把所有的key和value打印看看结果:
运行看看结果:
因为之前他在微信上把他的uin和imei发给我了,所以我一眼就看到了这里有他的imei和uin值,也就是说那个工具的确是通过这两个序列化文件来获取imei值和uin值然后计算密码的,所以我再一次相信他也是用MD5计算那个密码的,所以这时候我就不用他发给我的那个信息了,我就从这里打印的结果直接计算结果,然后在用sqlcipher.exe工具直接查看,竟然解开了:
所以再一次确认了微信的数据库加密算法没有变化,那为什么他还是没解开呢?因为最后也确认了他和我计算的密码是一样的?那么我就要怀疑他使用的sqlcipher.exe工具了,最后果然是工具出了问题,我把我发给他的工具就可以用了。所以这个过程我被他微信发给我的信息坑了,他被解密数据的工具坑了。不过不管怎么样都成功了。所以以后如果你在操作微信解密失败问题,一定不要怀疑微信算法变了,不可能变的。如果有错误可能这些原因:
第一、现在很多设备都有很多个imei值,一般是两个,所以如果一个失败了,就尝试第二个。因为你不知道微信获取的是哪个imei值。
第二、获取imei值我们会用简单的拨号和设置中进行查看,这里我用小米 4+6.0系统验证发现这两种方式查看的值是不一样的,而拨号的方式是正确的。
第三、就是有的同学imei和uin值都获取对了,但是计算MD5和全是字母小写这一点弄错了,也要注意。
如果以上都没有问题,那么还是解密失败,就请怀疑你使用给的sqlcipher.exe工具吧,不过没关系了,从现在开始我要带你们开发这个工具,以后只要用我的工具就可以了。
三、C++代码解密数据库
那么到这里本文就算结束了吗?本来是结束了,因为帮他搞定了解密,但是我就去看了那个工具,发现他查看消息和其他功能都是收费的,这我就不答应了,这么简单的功能还收费,我就喜欢做免费的东西,所以在那一刻之后我决定了自己开发这个工具,功能和他都是差不多,只需要导入MicroMsg目录就可以预览信息了。那么在写这个工具之前,我们不用C++来编写界面,因为我不会,我只会用Java写界面,但是SQLCipher官网中没有Java中可以使用的jar功能,但是我们在之前的文章已经在VS中用C++实践成功了,所以我们可以用Java开发JNI来调用dll文件,把解密工作放到C++中做,数据展示放到Java层做这样就没问题了。其实主要还是我不会C++的图形化开发,我也不想去折腾学习了,因为我觉得价值不是很大。而且用Java做我们可以回顾JNI开发知识也是一件很好的事情。
那么不多说了,先来解决第一件事就是利用之前的文章说的SQLCipher代码来解密微信数据库看看能否成功,代码修改很简单,直接把我们计算的密码替换一下,然后把微信的加密数据库EnMicroMsg.db放到工程目录下,运行即可:
可惜的是运行代码提示数据库加密了,也就是我们解密数据库失败了,但是我们用sqlcipher.exe工具查看都没有问题,所以这里的密码是没有问题的,但是哪里出问题呢?代码也是没问题,因为我们之前写的demo都没有问题,所以就怀疑微信的数据库加密做了一些其他设置,我们可能还需要设置一些东西,就跑去SQLCipher官网查看api:
然后找到这些内容,就尝试执行这些命令:
然后在执行程序:
这样就成功了,把userinfo数据表中的数据都成功打印出来了,到这里本文的内容就结束了,后面还有一篇文章介绍如何利用JNI把C++层的解密数据传递到Java层中进行展示,以及如何开发出工具。因为篇幅过长,本文就不在继续讲解了。
那么看完本文之后,了解到微信中会把uin值和imei值序列化到cfg文件中,所以从这里看到我们的确只需要MicroMsg目录就可以进行解密操作了,但是我也发现
加密数据库都放在这种类似于md5文件夹下面,所以我们为了后面更好的操作,所以我们要搞清楚这个文件夹名字怎么来的,这个比较简单,再去dex文件中跟踪即可:
点进去查看跟踪可以看到,这里其实我不想说了,因为我之前在网上看到其他人说了,这个文件夹的算法就是:MD5("mm"+uin).toLower 即可。所以我就直接告诉大家了。
当然因为现在微信作为最常用的聊天通信工具,很多人的聊天信息都保存了,当然微信官方说好了不会上传用户的聊天记录,所以有时候当我们无意中丢失了和朋友之间的聊天记录在找回来很麻烦了,比如手机摔坏了想找回聊天记录怎么办?这时候我们可以这么做吧手机的内存卡卸载下来,这一步一般如果不是一个喜欢动手的同学可以去找专业人员操作:
卸载下来之后直接可以用电脑访问,这时候看到就是有root身份直接访问微信的沙盒数据,然后直接用这种解密方式就可以找回微信信息进行保存即可。当然如果你在大马路上无意中捡到一部手机的话,如果无法解锁找到失主,最好的方式是交给JC叔叔,当然你可以还有其他办法找到失主,这里不方便多说,当然也有现在很多JC叔叔破案可以通过手机中的微信聊天记录找到线索,如果有了犯罪分子的手机可以通过这种方式进行操作。