Android获取微信聊天记录的过程详解

开门见山

1、手机获得root的最高权限

2、了解微信本地的目录结构

3、微信本地文件的读取权限

4、微信本地数据库的破解

5、找到相应的数据库表读取

一、手机获得root的最高权限

无论怎么操作,这个都是跳不过的前提,首先手机要root,才能访问别的app下面的数据库。root过程参考前面写的文章。

https://blog.csdn.net/hq222/article/details/89020608

二、了解微信本地的目录结构

/data/data/com.tencent.mm下就是微信本地的目录结构;本地数据库都在/data/data/com.tencent.mm/MicroMsg下面;

SharedPerferences文件都在 /data/data/com.tencent.mm/shared_prefs下面,这里存放的就是用户的一些个人私密信息,root之后可以利用RE管理器查看

                                                                   

三、修改微信文件的读取权限

int tx = RootCmd.execRootCmdSilent("chmod 777 -R " +WX_PATH);//每次读取前都要走这个方法,修改文件的权限
 public static int execRootCmdSilent(String cmd) {
        int result = -1;
        DataOutputStream dos = null;

        try {
            Process p = Runtime.getRuntime().exec("su");
            dos = new DataOutputStream(p.getOutputStream());

            Log.i(TAG, cmd);
            dos.writeBytes(cmd + "\n");
            dos.flush();
            dos.writeBytes("exit\n");
            dos.flush();
            p.waitFor();
            result = p.exitValue();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
每次准备读取数据库或者操作微信文件之前都需要执行一次该命令。Process localProcess = Runtime.getRuntime().exec("su")先通过这个命令, 使得当前app获取到root权限,然后再通过chmod命令来修改微信的data目录的读写权限,因为我们需要操作读取微信的数据库文件以及sp文件,所以必须要有微信文件的操作权限。

四、微信数据库密码的破解

微信的数据库密码是:MD5(手机的IMEI+微信UIN)的前7位(网上大神提供)

1、获取手机的IMEI

  TelephonyManager tm = (TelephonyManager) getApplicationContext().getSystemService(TELEPHONY_SERVICE);
imei = tm.getDeviceId();

需要权限:

 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

2、获取微信的UIN

微信的uin是存储在SharedPerferences里面,所以要在微信目录的shared_prefs文件夹里去查找,路径:shared_prefs/auth_info_key_prefs.xml

代码获取:

 public String getWxUin() {
        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");
                }
            }
            return mCurrWxUin;
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("huang", "获取微信uid失败,请检查auth_info_key_prefs文件权限");
        }
        return "";
    }

3、根据IMEI和uin获取数据库的密码

String pwd = initDbPassword(imei, uin);
 private String initDbPassword(String imei, String uin) {
        if (TextUtils.isEmpty(imei) || TextUtils.isEmpty(uin)) {
            return "";
        }
        String md5 = md5(imei + uin);
        Log.i("huang","md5=="+md5);
        String password = md5.substring(0, 7).toLowerCase();
        return password;
    }

4、数据库的父级文件夹名称的破解(重要!!!)

微信父级数据库的名称:MD5("mm"+auth_info_key_prefs.xml中解析出微信的uin码)

String dbParentsPath = md5("mm" + uin);
 public static String md5(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(string.getBytes());
            String result = "";
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result += temp;
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

5、复制数据库

注意:为啥会有这一步,因为一个数据库文件不能被多次连接,只要我们一成功连接上那个db文件,微信的客户端就会自动退出登录,并且会出现异常。所有我现在的做法是把这个db文件拷贝到我们自己的app目录下,再进行连接。

 public static boolean copyFile(String oldPath, String newPath) {
        deleteFolderFile(newPath,true);
        InputStream inStream = null;
        FileOutputStream fs = null;
        try {
            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPath);
            Boolean flag = oldfile.exists();
            if (oldfile.exists()) { //文件存在时
                inStream = new FileInputStream(oldPath); //读入原文件
                fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[2048];
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread; //字节数 文件大小
                    fs.write(buffer, 0, byteread);
                }
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
                if (fs != null) {
                    fs.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

6、读取数据库的聊天记录

首先看一下微信的数据库的结构以及聊天记录的表结构

这只是一小部分,微信数据库中表特别多,不过联系人信息在rcontact表中,聊天记录在message表中

message表结构:

所以可以根据表中显示读取想要的聊天记录

 private void openWxDb(File dbFile,String mDbPassword) {
        Context context = DemoApplication.getInstance();
        SQLiteDatabase.loadLibs(context);
        SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
            @Override
            public void preKey(SQLiteDatabase database) {
            }

            @Override
            public void postKey(SQLiteDatabase database) {
                database.rawExecSQL("PRAGMA cipher_migrate;"); //兼容2.0的数据库
            }
        };

        try {
            //打开数据库连接
            SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, mDbPassword, null, hook);
            Cursor c1 = db.rawQuery("select * from message where type=1", null);
            while (c1.moveToNext()) {
                String talker = c1.getString(c1.getColumnIndex("talker"));
                String content = c1.getString(c1.getColumnIndex("content"));
                String type = c1.getString(c1.getColumnIndex("type"));
                Log.i("huang","content=="+content);
                Log.i("huang","talker=="+talker);
                Log.i("huang","type=="+type);
                record=record+"/"+content;
            }
            tvRecord.setText(record);
            c1.close();
            db.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这里读取用到的是:

compile 'net.zetetic:android-database-sqlcipher:3.5.4@aar'

难点总结

1、手机必须root

2、让当前app获取su权限,以及修改微信目录的读写权限

3、破解微信的数据库密码

4、数据库的父级文件夹名称的获取

5、数据库必须复制出来再读取

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值