开门见山

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() {@Overridepublic void preKey(SQLiteDatabase database) {}@Overridepublic 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、数据库必须复制出来再读取

Android获取微信聊天记录的过程详解相关推荐

  1. Android init.rc文件解析过程详解(三)

    Android init.rc文件解析过程详解(三) 三.相关结构体 1.listnode listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了l ...

  2. 安卓 linux init.rc,[原创]Android init.rc文件解析过程详解(二)

    Android init.rc文件解析过程详解(二) 3.parse_new_section代码如下: void parse_new_section(struct parse_state *state ...

  3. Android init.rc文件解析过程详解(二)

    Android init.rc文件解析过程详解(二) 3.parse_new_section代码如下: void parse_new_section(struct parse_state *state ...

  4. Android init.rc文件解析过程详解(一)

        Android init.rc文件解析过程详解(一) 一.init.rc文件结构介绍 init.rc文件基本组成单位是section, section分为三种类型,分别由三个关键字(所谓关键字 ...

  5. php android 图片上传,android上传图片到PHP的过程详解

    这篇文章主要介绍了android上传图片到PHP的过程详解,需要的朋友可以参考下 今天在做上传头像的时候,总是提交连接超时错误,报错信息如下:XXXXXXSokcetTimeOutXXXXXXXX 然 ...

  6. Android签名机制之---签名验证过程详解

    一.前言 今天是元旦,也是Single Dog的嚎叫之日,只能写博客来祛除寂寞了,今天我们继续来看一下Android中的签名机制的姊妹篇:Android中是如何验证一个Apk的签名.在前一篇文章中我们 ...

  7. Android 系统服务管家servicemanager启动过程详解

    Android考虑到移动设备耗电以及跨进程通信效率等因素,基于OpenBinder专门为进程通信开发了一套框架:binder.例如,客户端程序需要获取WindowManager,TelephonyMa ...

  8. Unity 之 发布WebGL转微信小游戏过程详解

    Unity 之 发布WebGL转微信小游戏 前言 一,准备工作 1.1 下载插件 1.2 下载Unity 1.3 安装微信开发者工具 1.4 创建小程序 二,开始转换 2.1 创建项目 2.2 Mac ...

  9. 如何获取微信用户的Openid详解(微信网页授权)

    如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域名的说明 1.在微信公众号请求用户网页授权之前,开发者需要先到公众平台官 ...

最新文章

  1. YOLOV5的多主干网络backbone实现(Mobilenetv3Small、EagleEye、EfficientNetLite-0、PP-LCNet-1x、SwinTrans-YOLOv5等)
  2. Spring进行表单验证
  3. 用一个栈实现另一个栈的排序
  4. 计算机光驱参数,请问,电脑光驱插入关盘,打开时显示“参数不正确,无法打开”,这是什么故障,怎么处理?...
  5. 哪些深度相机有python接口_python 从深度相机realsense生成pcl点云
  6. 元胞自动机与相关理论和方法
  7. OPA 5 - CreateButtonTest creates CreateButtonSteps
  8. 容器,Docker, Kubernetes和Kyma,以及Kyma对SAP的意义
  9. gson生成jsonobject_使用GSON将字符串解析为JsonObject会产生IllegalStateException:这不是JSON对象...
  10. 【CodeForces - 215A】Bicycle Chain (水题)
  11. 在哪个国家生活幸福?24秒看完联合国10年报告
  12. Bootstrap-CSS-排版
  13. webpack中library和libraryTarget详解
  14. 仙剑奇侠传7报错:the following components are required to run this program.microsoft visual c++ 2015 runtime
  15. java -jar命令
  16. python实现mysql的读写分离及负载均衡
  17. Java语言速览:StackOverflow
  18. Cadence原理图绘制总线使用技巧
  19. jquery日历插件 途牛_js jquery 实现 排班,轮班,日历,日程。使用fullcalendar 插件...
  20. poi tl 判断空值_使用poi-tl操作word模板

热门文章

  1. Python面向对象实现图书管理系统
  2. 研发知识:MDD、MDF是什么?
  3. [随心译]2017.8.7-这些难以置信的地球太空夜景图实际上全是假货
  4. \xe4\xb8\xad\xe6\x96\x87 phython 字符编码乱码问题
  5. 实时数仓利器之Doris
  6. linux 监控丢包 脚本,ping发现掉包报警的shell代码
  7. Python不掉包初探自然语言处理One-Hot编码与解码
  8. Linux-less
  9. 2023年软件测试的前景?测试工程师技能提升,进阶自动化测试...
  10. 今天主要学习vue的一些原理,尤其是vueComponent与Vue的关系,个人觉得值得反复回味,很巧妙