From 68c0e92aaccb9b9b1b9391f9f0ee3251f41de339 Mon Sep 17 00:00:00 2001 From: ppwwyyxx Date: Fri, 21 Nov 2014 13:09:01 +0800 Subject: [PATCH] init --- README.md | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ decrypt_db.sh | 23 ++++++++++++ dump.py | 70 ++++++++++++++++++++++++++++++++++++ lib/Msg.py | 23 ++++++++++++ lib/sqlcipher | Bin 0 -> 54064 bytes 5 files changed, 213 insertions(+) create mode 100644 README.md create mode 100755 decrypt_db.sh create mode 100755 dump.py create mode 100644 lib/Msg.py create mode 100755 lib/sqlcipher diff --git a/README.md b/README.md new file mode 100644 index 0000000..1df6cc3 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +## Render WeChat Messages from Android + +## 安卓微信消息记录分析工具 + +WeChat, as the most popular mobile IM app in China, doesn't provide any methods to read its message history. +Customers are not able to analyze their own chat messages or interact with other data analysis tools. + +We provide this tool that can parse WeChat messages from a rooted android phone. +This is necessary to provide interoperability between WeChat messages and other message analysis tools. +As examples, we provide sample scripts to obtain statistics of the message history and +render the messages into self-contained html files including voice messages, images, emojis, videos, etc. +Users can also write custom programs based on this tool to manage their chat messages. + +The tool is last verified to work with latest version of WeChat on 2025/01/01. +If the tool works for you, please take a moment to add your phone/OS to [the wiki](https://github.com/ppwwyyxx/wechat-dump/wiki). + +## How to use: + +#### Dependencies: ++ adb and rooted android phone connected to a Linux/Mac OSX/Win10+Bash. ++ Python >= 3.8 ++ sox (command line tools) ++ Silk audio decoder (included; build it with `./third-party/compile_silk.sh`) ++ Other python dependencies: `pip install -r requirements.txt`. + +#### Get Necessary Data: + +1. Pull database file and (for older WeChat versions) avatar index: + + Automatic: `./android-interact.sh db`. It may use an incorrect userid. + + Manual: + + Figure out your `${userid}` by inspecting the contents of `/data/data/com.tencent.mm/MicroMsg` on the __root__ filesystem of the device. + It should be a 32-character-long name consisting of hexadecimal digits. + + Get `/data/data/com.tencent.mm/MicroMsg/${userid}/EnMicroMsg.db` from the device. +2. Decode `EnMicroMsg.db`. We do not provide instructions to do that. +3. Copy the unencrypted WeChat user resource directory `/data/data/com.tencent.mm/MicroMsg/${userid}/{avatar,emoji,image2,sfs,video,voice2}` from the phone to the `resource` directory: + + `./android-interact.sh res` + + Change `RES_DIR` in the script if the location of these directories is different on your phone. + For older version of WeChat, the directory may be `/mnt/sdcard/tencent/MicroMsg/` + + This can take a while. It can be faster to first archive it with `tar` with or without compression, and then copy the archive, + `busybox tar` is recommended as the Android system's `tar` may choke on long paths. + + In the end, we need a `resource` directory with the following subdir: `avatar,emoji,image2,sfs,video,voice2`. + +4. (Optional) Install and start a WXGF decoder server on an android device. Without this, certain WXGF images will not be rendered or will be rendered in low resolution. + See [WXGFDecoder](WXGFDecoder) for instructions. + +4. (Optional) Download the emoji cache from [here](https://github.com/ppwwyyxx/wechat-dump/releases/download/0.1/emoji.cache.tar.bz2) + and decompress it under `wechat-dump`. This will avoid downloading too many emojis during rendering. + + wget -c https://github.com/ppwwyyxx/wechat-dump/releases/download/0.1/emoji.cache.tar.bz2 + tar xf emoji.cache.tar.bz2 + +#### Run: ++ Parse and dump text messages of __every__ chat (requires decoded database): + + ``` + ./dump-msg.py decoded.db output_dir + ``` + ++ List all chats (required decoded database): + + ``` + ./list-chats.py decoded.db + ``` + ++ Generate statistics report on text messages (requires `output_dir` from `./dump-msg.py`): + + ``` + ./count-message.sh output_dir + ``` + ++ Dump messages of one contact to html, containing voice messages, emojis, and images (requires decoded database and `resource`): + + ``` + ./dump-html.py "" + ``` + + * The output file is `output.html`. Check `./dump-html.py -h` to use different input/output paths. + * Add `--wxgf-server ws://xx.xx.xx.xx:xxxx` to use a WXGF decoder server. + +### Examples: +Screenshots of generated html: + +![byvoid](https://github.com/ppwwyyxx/wechat-dump/raw/master/screenshots/byvoid.jpg) + +See [here](http://ppwwyyxx.com/static/wechat/example.html) for an example html. + +### TODO List (help needed!) +* After chat history migration, some emojis in the `EmojiInfo` table don't have corresponding URLs but only a md5 - + they are not downloaded by WeChat until the message needs to be displayed. We don't know how to manually download these emojis. +* Decoding WXGF images using an android app is too complex. Looking for an easier way (e.g. qemu). +* Fix rare unhandled message types: > 10000 and < 0 +* Better user experiences... see `grep 'TODO' wechat -R` + +### Donate! + +[paypal] + diff --git a/decrypt_db.sh b/decrypt_db.sh new file mode 100755 index 0000000..a5d02a3 --- /dev/null +++ b/decrypt_db.sh @@ -0,0 +1,23 @@ +#!/bin/bash -e +# File: decrypt_db.sh +# Date: Fri Nov 21 13:07:33 2014 +0800 +# Author: Yuxin Wu + +MMSGDB=$1 +imei=$2 +uin=$3 + +if [[ -z "$1" || -z "$2" || -z "$3" ]]; then + echo "Usage: $0 " + exit +fi + +KEY=$(echo -n "$imei$uin" | md5sum | cut -b 1-7) + +LD_LIBRARY_PATH=./lib ./lib/sqlcipher $MMSGDB << EOF +PRAGMA key='$KEY'; +PRAGMA cipher_use_hmac = off; +ATTACH DATABASE "decoded_database.db" AS decoded_database KEY ""; +SELECT sqlcipher_export("decoded_database"); +DETACH DATABASE decoded_database; +EOF diff --git a/dump.py b/dump.py new file mode 100755 index 0000000..3e97f37 --- /dev/null +++ b/dump.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python2 +# -*- coding: UTF-8 -*- +# File: dump.py +# Date: Fri Nov 21 13:07:58 2014 +0800 +# Author: Yuxin Wu + +import sqlite3 +from collections import defaultdict +from pprint import PrettyPrinter +pp = PrettyPrinter() +def log(x): print repr(x).decode('unicode-escape') +from lib.Msg import WeChatMsg + +""" tables in concern: +emojiinfo +imginfo2 +addr_upload2 +chatroom +message +rcontact + +""" + +class WeChatDBParser(object): + def __init__(self, db_fname): + """ db_fname: EnMicroMsg.db""" + self.db_fname = db_fname + self.db_conn = sqlite3.connect(self.db_fname) + self.cc = self.db_conn.cursor() + self.contacts = {} + + def _parse_contact(self): + contacts = self.cc.execute( +""" +SELECT username,conRemark,nickname +FROM rcontact +""") + for row in contacts: + username, remark, nickname = row + if remark: + self.contacts[username] = remark + else: + self.contacts[username] = nickname + + def _parse_msg(self): + msgs_by_talker = defaultdict(list) + db_msgs = self.cc.execute( +""" +SELECT {} +FROM message ORDER BY createTime +""".format(','.join(WeChatMsg.FIELDS))) + for row in db_msgs: + msg = WeChatMsg(row) + msgs_by_talker[msg.talker].append(msg) + msgs_by_talker = dict([ + (self.contacts[k], sorted(v, key=lambda x: x.createTime)) + for k, v in msgs_by_talker.iteritems()]) + for k, v in msgs_by_talker.iteritems(): + for msg in v: + msg.talker = k + pp.pprint(msgs_by_talker.items()[0]) + + def parse(self): + self._parse_contact() + msg = self._parse_msg() + pass + +if __name__ == '__main__': + parser = WeChatDBParser('./decoded_database.db') + parser.parse() diff --git a/lib/Msg.py b/lib/Msg.py new file mode 100644 index 0000000..40c3714 --- /dev/null +++ b/lib/Msg.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python2 +# -*- coding: UTF-8 -*- +# File: Msg.py +# Date: Fri Nov 21 12:15:27 2014 +0800 +# Author: Yuxin Wu + +from datetime import datetime + +class WeChatMsg(object): + """ fields in concern""" + FIELDS = ["msgSvrId","type","isSend","createTime","talker","content","imgPath"] + + def __init__(self, row): + """ row: a tuple corresponding to FIELDS""" + assert len(row) == len(WeChatMsg.FIELDS) + for f, v in zip(WeChatMsg.FIELDS, row): + setattr(self, f, v) + self.createTime = datetime.fromtimestamp(self.createTime / 1000) + if self.content: + self.content = self.content.encode('utf-8') + + def __repr__(self): + return "{}:{}:{}".format(self.talker.encode('utf-8') if not self.isSend else 'me', self.createTime, self.content) diff --git a/lib/sqlcipher b/lib/sqlcipher new file mode 100755 index 0000000000000000000000000000000000000000..4f3b3d43be217d78c0119bb09429ab6b1499db05 GIT binary patch literal 54064 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 literal 0 HcmV?d00001