Android动态破解微信本地数据库(EnMicroMsg.db)
最近在公司接了一个任务,需要在几百台手机上安装一个app,目的是获取微信里面的通讯录,并且定时的把他发送到我们的服务器上。当时依次尝试的如下几个方案:
1.通过群控,将好友截图发送到服务端(python),利用python的图像识别库来获取好友的信息。
2.开发一个app,使用android自带AccessibilityService,模拟用户操作微信,然后获取屏幕中的内容。
3.破解微信的本地数据库。
非常尴尬的是前两个都失败了,否则也不会想到第三个方案了。第一个失败的原因是,利用图像识别,有些很相近的文字(i,1,l,h,n)识别成功率不高;第二个失败的原因是在于模拟用户操作的阶段无法达到预计的效果,也就导致了获取不到想要的屏幕内容。(前两个失败有可能是因为个人技术问题,无法实现)
但是重点来了:第三个我们成功了
我们是怎么知道微信把用户以及聊天的信息存到了本地数据库呢?
当我们打开手机的飞行模式的时候,打开微信,依旧可以看到里面的通讯录以及聊天记录。那么就说明微信肯定是将你能看到的所有信息都保存在了本地数据库里面,只是他将本地数据库加了密。既然存在了本地,我们就有办法把它取出来。
本地数据库的密码是什么呢?
请具体参考大神的文章,他通过反编译获取到微信的加密规则,特别厉害!
上述文章讲解主要是静态破解数据库,我们就基于他的静态破解方法,介绍下如何在代码中动态破解。不想看的同学们,我就直接介绍下微信本地数据库的加密规则了:
1.获取手机IMEI码
2.获取当前登录微信账号的uin(存储在sp里面)
3.拼接IMEI和uin
4.将拼接完的字符串进行md5加密
5.截取加完密的字符串的前七位(字母必须为小写)
那七位字符串就是数据库的密码了。因为微信已经有数亿的用户了,并且本地数据库又是存在用户的手机上,所以微信肯定不会轻易的对数据库进行大规模修改,所以密码的加密规则也是不可能变的,大家就放心用吧!
适用范围:已经获取root权限的手机
一、大致浏览下微信的目录
二、授予当前app管理员权限以及修改微信目录的读写权限
- public static final String WX_ROOT_PATH = "/data/data/com.tencent.mm/";
- execRootCmd("chmod 777 -R " + WX_ROOT_PATH);
- /**
- * 执行linux指令
- *
- * @param paramString
- */
- public void execRootCmd(String paramString) {
- try {
- Process localProcess = Runtime.getRuntime().exec("su");
- Object localObject = localProcess.getOutputStream();
- DataOutputStream localDataOutputStream = new DataOutputStream((OutputStream) localObject);
- String str = String.valueOf(paramString);
- localObject = str + "\n";
- localDataOutputStream.writeBytes((String) localObject);
- localDataOutputStream.flush();
- localDataOutputStream.writeBytes("exit\n");
- localDataOutputStream.flush();
- localProcess.waitFor();
- localObject = localProcess.exitValue();
- } catch (Exception localException) {
- localException.printStackTrace();
- }
- }
每次准备读取数据库之前都需要执行一次该命令。Process localProcess = Runtime.getRuntime().exec("su")先通过这个命令,使得当前app获取到root权限,然后再通过chmod命令来修改微信的data目录的读写权限,因为我们需要操作读取微信的数据库文件以及sp文件,所以必须要有微信文件的操作权限。
三、获取手机IMEI
- /**
- * 获取手机的imei码
- *
- * @return
- */
- private void initPhoneIMEI() {
- TelephonyManager tm = (TelephonyManager) MyApplication.getContextObject().getSystemService(TELEPHONY_SERVICE);
- mPhoneIMEI = tm.getDeviceId();
- }
记得添加权限
- <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
四、获取微信的uin
- private static final String WX_SP_UIN_PATH = WX_ROOT_PATH + "shared_prefs/auth_info_key_prefs.xml";
- /**
- * 获取微信的uid
- * 微信的uid存储在SharedPreferences里面
- * 存储位置\data\data\com.tencent.mm\shared_prefs\auth_info_key_prefs.xml
- */
- private void initCurrWxUin() {
- mCurrWxUin = null;
- File file = new File(WX_SP_UIN_PATH);
- try {
- FileInputStream in = new FileInputStream(file);
- SAXReader saxReader = new SAXReader();
- Document document = saxReader.read(in);
- Element root = document.getRootElement();
- List<Element> elements = root.elements();
- for (Element element : elements) {
- if ("_auth_uin".equals(element.attributeValue("name"))) {
- mCurrWxUin = element.attributeValue("value");
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- LogUtil.log("获取微信uid失败,请检查auth_info_key_prefs文件权限");
- }
- }
微信的uin是存放在sharedPerferences文件夹里面的,具体路径为\data\data\com.tencent.mm\shared_prefs\auth_info_key_prefs.xml。让我们来打开这个xml文件看看里面到底是什么样子的,还有我们需要的uin到底是存放在什么地方:
五、生成数据库密码
- /**
- * 根据imei和uin生成的md5码,获取数据库的密码(去前七位的小写字母)
- *
- * @param imei
- * @param uin
- * @return
- */
- private void initDbPassword(String imei, String uin) {
- if (TextUtils.isEmpty(imei) || TextUtils.isEmpty(uin)) {
- LogUtil.log("初始化数据库密码失败:imei或uid为空");
- return;
- }
- String md5 = md5(imei + uin);
- String password = md5.substring(0, 7).toLowerCase();
- mDbPassword = password;
- }
- /**
- * md5加密
- *
- * @param content
- * @return
- */
- private String md5(String content) {
- MessageDigest md5 = null;
- try {
- md5 = MessageDigest.getInstance("MD5");
- md5.update(content.getBytes("UTF-8"));
- byte[] encryption = md5.digest();//加密
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < encryption.length; i++) {
- if (Integer.toHexString(0xff & encryption[i]).length() == 1) {
- sb.append("0").append(Integer.toHexString(0xff & encryption[i]));
- } else {
- sb.append(Integer.toHexString(0xff & encryption[i]));
- }
- }
- return sb.toString();
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
这一步比较容易,通过拼接字符串以及md5加密后就可以获取到数据库的密码
六、查找微信目录下的数据库文件
- public static final String WX_ROOT_PATH = "/data/data/com.tencent.mm/";
- public static final String WX_ROOT_PATH = "/data/data/com.tencent.mm/";
- private static final String WX_DB_DIR_PATH = WX_ROOT_PATH + "MicroMsg";
- private List<File> mWxDbPathList = new ArrayList<>();
- private static final String WX_DB_FILE_NAME = "EnMicroMsg.db";
- File wxDataDir = new File(WX_DB_DIR_PATH);
- mWxDbPathList.clear();
- searchFile(wxDataDir, WX_DB_FILE_NAME);
- /**
- * 递归查询微信本地数据库文件
- *
- * @param file 目录
- * @param fileName 需要查找的文件名称
- */
- private void searchFile(File file, String fileName) {
- if (file.isDirectory()) {
- File[] files = file.listFiles();
- if (files != null) {
- for (File childFile : files) {
- searchFile(childFile, fileName);
- }
- }
- } else {
- if (fileName.equals(file.getName())) {
- mWxDbPathList.add(file);
- }
- }
- }
七、连接数据库
终于到了最关键的一步了。这时候需要注意两点:
- private String mCurrApkPath = "/data/data/" + MyApplication.getContextObject().getPackageName() + "/";
- private static final String COPY_WX_DATA_DB = "wx_data.db";
- //处理多账号登陆情况
- for (int i = 0; i < mWxDbPathList.size(); i++) {
- File file = mWxDbPathList.get(i);
- String copyFilePath = mCurrApkPath + COPY_WX_DATA_DB;
- //将微信数据库拷贝出来,因为直接连接微信的db,会导致微信崩溃
- copyFile(file.getAbsolutePath(), copyFilePath);
- File copyWxDataDb = new File(copyFilePath);
- openWxDb(copyWxDataDb);
- }
- /**
- * 复制单个文件
- *
- * @param oldPath String 原文件路径 如:c:/fqf.txt
- * @param newPath String 复制后路径 如:f:/fqf.txt
- * @return boolean
- */
- public void copyFile(String oldPath, String newPath) {
- try {
- int byteRead = 0;
- File oldFile = new File(oldPath);
- if (oldFile.exists()) { //文件存在时
- InputStream inStream = new FileInputStream(oldPath); //读入原文件
- FileOutputStream fs = new FileOutputStream(newPath);
- byte[] buffer = new byte[1444];
- while ((byteRead = inStream.read(buffer)) != -1) {
- fs.write(buffer, 0, byteRead);
- }
- inStream.close();
- }
- } catch (Exception e) {
- System.out.println("复制单个文件操作出错");
- e.printStackTrace();
- }
- }
- /**
- * 连接数据库
- *
- * @param dbFile
- */
- private void openWxDb(File dbFile) {
- Context context = MyApplication.getContextObject();
- SQLiteDatabase.loadLibs(context);
- SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
- public void preKey(SQLiteDatabase database) {
- }
- public void postKey(SQLiteDatabase database) {
- database.rawExecSQL("PRAGMA cipher_migrate;"); //兼容2.0的数据库
- }
- };
- try {
- //打开数据库连接
- SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, mDbPassword, null, hook);
- //查询所有联系人(verifyFlag!=0:公众号等类型,群里面非好友的类型为4,未知类型2)
- Cursor c1 = db.rawQuery("select * from rcontact where verifyFlag = 0 and type != 4 and type != 2 and nickname != '' limit 20, 9999", null);
- while (c1.moveToNext()) {
- String userName = c1.getString(c1.getColumnIndex("username"));
- String alias = c1.getString(c1.getColumnIndex("alias"));
- String nickName = c1.getString(c1.getColumnIndex("nickname"));
- }
- c1.close();
- db.close();
- } catch (Exception e) {
- LogUtil.log("读取数据库信息失败" + e.toString());
- // e.printStackTrace();
- }
- }
- compile 'net.zetetic:android-database-sqlcipher:3.5.4@aar'
关于SQLCipher的详细使用方法可以参考其官网https://www.zetetic.net/sqlcipher/sqlcipher-for-android/
八、sqlcipher图形工具的使用
通过这个工具,我们可以快速的查看微信的db文件里面有哪些表,每个表里面有哪些字段,然后我们就可以在代码中写出相应的sql语句来查询我们需要的数据了
使用方法也很简单
九、总结
Android动态破解微信本地数据库(EnMicroMsg.db)相关推荐
- 直接利用Android手机破解微信加密数据库EnMicroMsg.db
※首先,简单介绍一下微信加密数据库EnMicroMsg.db的破解方法: 要先批评一下微信,居然用开源的数据库加密方式,这不是一破解一个准吗... 如果你的模拟器或者真机已经获得了root权限,就可以 ...
- 利用Android手机破解微信加密数据库EnMicroMsg.db文件
要先批评一下微信,居然用开源的数据库加密方式,这不是一破解一个准吗? 如果你的模拟器或者真机已经获得了root权限,就可以直接将记录聊天记录的数据库文件拷贝出来,数据库文件具体存放位置如下: 在/da ...
- Android逆向_微信本地数据库解密与删除聊天记录恢复完全教程
# 前言 在电子数据取证过程中,对微信本地数据库的解密.提取与恢复是非常重要的工作内容.本文以华为mate系列手机和最新版的微信(7.0.3)为例,通过总结互联网上已经发表的文章经验,主要针对**华为 ...
- 破解微信本地数据库,无法找回删除的聊天记录
[说明:操蛋的微信从4.0后本地数据库都加密了,密码是IMEI+UIN取MD5 32位小写加密前7作为密码] [数据库文件请ROOT后用RE浏览器得到] [UIN 文件路径:/data/data/ ...
- Android打开微信本地数据库详细步骤二
特别声明:本文章只是用于技术交流,不可用于非法行为. 阅读过上篇文章后,我想你一定去取出来微信本地数据库文件EnmicroMsg.db,但是取出来有什么用呢?又打不开,加密了.好比邂逅了个穿着铁内裤的 ...
- 安卓微信本地数据库解密与删除聊天记录恢复完全教程
安卓微信本地数据库解密与删除聊天记录恢复完全教程 前言 正文 经验回顾 新的问题 解决华为旧备份数据导出问题 解密索引数据库 先要解密微信消息库 解密索引库 从索引库恢复被删除的消息 总结 [原创内容 ...
- PC微信机器人之实战分析微信本地数据库获取密码
今天主要讨论一下怎么找PC微信本地数据库的密钥,我们知道微信使用的数据库是sqlite3,然后数据库是经过 aes 加密的,我们需要找到aes的密钥,才能解密,然后进行数据库操作.思路是在微信登陆的时 ...
- Android studio如何查看本地数据库
android开发有时候涉及到本地存储的时候,需要用到数据库,当开发者需要查看本地数据库的内容时,就会发现非常麻烦.以前我觉得google在这一方面是完全没有倾听开发者的呼声呀!这是有多麻烦就有多麻烦 ...
- Android中实现微信本地视频发布到朋友圈功能
编码美丽 2016-11-14 17:49 一.前言 前一篇文章已经详细介绍了如何使用Xposed框架编写第一个微信插件:摇骰子和猜拳作弊 本文继续来介绍如何使用Xposed框架编写第二个微信插件,可 ...
- 破解微信数据库 并查询数据上传服务器
由于工作需求破解了微信的数据库 并获取想要的信息上传服务器 都是内部手机 网上大神反编译了微信 发现微信的数据库是通过 手机的IMEI(唯一识别码) + UIN 大写的IMEI + UIN 进行MD5 ...
最新文章
- javaScript的调试(二)
- 你还在使用 try-catch-finally 关闭资源?
- HEOI2016/TJOI2016 字符串问题
- 内核中的HZ 及延迟等
- jdbc java例子_Spring JDBC 例子
- Numpy-矩阵的分割
- c语言函数能改变指针吗,如何修改传递给C中函数的指针?
- 学计算机用多大的u盘合适,u盘装系统需要多大的u盘|装系统需要多大的U盘
- 百度文库下载助手使用说明
- 单例模式几种实现方式和代码
- truncate table(截断表)
- Java多线程(7):JUC(下)
- 电机对应的电流计算方式及电线、端子的选型
- aria2简单下载脚本
- 免线圈高频无线充电IC无线供电芯片方案芯片XKT-511
- fatal: unable to access ‘xxx‘: schannel: failed to receive handshake, SSL/TLS connection f...
- 快速学会使用association和collection
- 云计算学习1——OpenStack云计算安装部署步骤图文并茂(先电2.2)
- 中科呐喊WiFi热点广告机,WiFi营销及创意展示神器
- 电脑测试瓶颈的软件,电脑性能检测工具(Fresh Diagnose)