From 8db2d6d11a2c034eeedd07fcb50df9024bdf0792 Mon Sep 17 00:00:00 2001 From: ppwwyyxx Date: Tue, 3 Nov 2015 15:16:27 -0500 Subject: [PATCH] use newer version of sqlcipher --- README.md | 6 ++- android-interact.sh | 10 ++-- decrypt-db.py | 51 ++++++++++++++++++ decrypt-db.sh => legacy/decrypt-db.sh | 4 +- {third-party => legacy}/sqlcipher/LICENSE | 0 {third-party => legacy}/sqlcipher/README.md | 0 .../sqlcipher/darwin/64bit/.libs/sqlite3 | Bin .../sqlcipher/darwin/64bit/sqlcipher | 0 .../sqlcipher/linux/32bit/libsqlcipher.so.0 | Bin .../sqlcipher/linux/32bit/sqlcipher | Bin .../sqlcipher/linux/64bit/libsqlcipher.so.0 | Bin .../sqlcipher/linux/64bit/sqlcipher | Bin 12 files changed, 64 insertions(+), 7 deletions(-) create mode 100755 decrypt-db.py rename decrypt-db.sh => legacy/decrypt-db.sh (91%) rename {third-party => legacy}/sqlcipher/LICENSE (100%) rename {third-party => legacy}/sqlcipher/README.md (100%) rename {third-party => legacy}/sqlcipher/darwin/64bit/.libs/sqlite3 (100%) rename {third-party => legacy}/sqlcipher/darwin/64bit/sqlcipher (100%) rename {third-party => legacy}/sqlcipher/linux/32bit/libsqlcipher.so.0 (100%) rename {third-party => legacy}/sqlcipher/linux/32bit/sqlcipher (100%) rename {third-party => legacy}/sqlcipher/linux/64bit/libsqlcipher.so.0 (100%) rename {third-party => legacy}/sqlcipher/linux/64bit/sqlcipher (100%) diff --git a/README.md b/README.md index f014eae..787b71d 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ __NEWS__: WeChat 6.0+ use silk to encode audio. The code is updated. + python-PIL + [PyQuery](https://pypi.python.org/pypi/pyquery/1.2.1) + [pysox](https://pypi.python.org/pypi/pysox/0.3.6.alpha) ++ [pysqlcipher](https://pypi.python.org/pypi/pysqlcipher) + numpy + python-csscompressor(optional) + adb and rooted android phone connected to PC @@ -39,12 +40,15 @@ __NEWS__: WeChat 6.0+ use silk to encode audio. The code is updated. + Find IMEI in system settings + Decrypt database, will produce `decrypted.db`: ``` - ./decrypt-db.sh + ./decrypt-db.py ``` + NOTE: you may need to try different ways to getting imei & uin, because things behave differently on different phones. +Also, if the decryption doesn't work with pysqlcipher, maybe try the version of sqlcipher in `legacy`. + + Get WeChat user resource directory from your phone to `resource` directory: + `./android-interact.sh res` diff --git a/android-interact.sh b/android-interact.sh index 9992fc1..ba73156 100755 --- a/android-interact.sh +++ b/android-interact.sh @@ -18,7 +18,7 @@ adb root if [[ $1 == "uin" ]]; then adb pull $MM_DIR/shared_prefs/system_config_prefs.xml 2>/dev/null - uin=$(grep 'default_uin' system_config_prefs.xml | $GREP -o 'value="[0-9]*' | cut -c 8-) + uin=$($GREP 'default_uin' system_config_prefs.xml | $GREP -o 'value="-\?[0-9]*' | cut -c 8-) [[ -n $uin ]] || { >&2 echo "Failed to get wechat uin. You can try other methods, or report a bug." exit 1 @@ -26,7 +26,7 @@ if [[ $1 == "uin" ]]; then rm system_config_prefs.xml echo "Got wechat uin: $uin" elif [[ $1 == "imei" ]]; then - imei=$(adb shell dumpsys iphonesubinfo | grep 'Device ID' | $GREP -o '[0-9]\+') + imei=$(adb shell dumpsys iphonesubinfo | $GREP 'Device ID' | $GREP -o '[0-9]\+') [[ -n $imei ]] || { >&2 echo "Failed to get imei. You can try other methods, or report a bug." exit 1 @@ -78,9 +78,9 @@ elif [[ $1 == "db" || $1 == "res" ]]; then fi elif [[ $1 == "db-decrypt" ]]; then echo "Getting uin..." - $0 uin | tail -n1 | grep -o '[0-9]*' | tee /tmp/uin + $0 uin | tail -n1 | $GREP -o '-\?[0-9]*' | tee /tmp/uin echo "Getting imei..." - $0 imei | tail -n1 | grep -o '[0-9]*' | tee /tmp/imei + $0 imei | tail -n1 | $GREP -o '[0-9]*' | tee /tmp/imei echo "Getting db..." $0 db echo "Decrypting db..." @@ -90,7 +90,7 @@ elif [[ $1 == "db-decrypt" ]]; then >&2 echo "Failed to get imei or uin. See README for manual methods." exit 1 fi - ./decrypt-db.sh EnMicroMsg.db $imei $uin + ./decrypt-db.py EnMicroMsg.db $imei $uin rm /tmp/{uin,imei} echo "Done. See decrypted.db" else diff --git a/decrypt-db.py b/decrypt-db.py new file mode 100755 index 0000000..958a926 --- /dev/null +++ b/decrypt-db.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python2 +# -*- coding: UTF-8 -*- +# File: decrypt-db.py +# Author: Yuxin Wu + +from argparse import ArgumentParser +from pysqlcipher import dbapi2 as sqlite + +from hashlib import md5 +import sys +import os + +def get_args(): + parser = ArgumentParser() + parser.add_argument('db', help='path to EnMicroMsg.db') + parser.add_argument('imei', help='15 digit IMEI of your phone') + parser.add_argument('uin', help='WeChat UIN') + parser.add_argument('--output', help='output decrypted database', + default='decrypted.db') + args = parser.parse_args() + return args + +def get_key(imei, uin): + a = md5(imei + uin) + return a.hexdigest()[:7] + +if __name__ == '__main__': + args = get_args() + + output = args.output + if os.path.isfile(output): + print "{} already exists. Remove? (y/n)".format(args.output), + ans = raw_input() + if ans not in ['y', 'Y']: + print "Bye!" + sys.exit() + os.unlink(argsos.output) + key = get_key(args.imei, args.uin) + print "KEY: {}".format(key) + + print "Dump decrypted database... " + conn = sqlite.connect(args.db) + c = conn.cursor() + c.execute("PRAGMA key = '" + key + "';") + c.execute("PRAGMA cipher_use_hmac = OFF;") + c.execute("PRAGMA cipher_page_size = 1024;") + c.execute("PRAGMA kdf_iter = 4000;") + c.execute("ATTACH DATABASE '" + args.output + "' AS db KEY '';") + c.execute("SELECT sqlcipher_export('db');" ) + c.execute("DETACH DATABASE db;" ) + c.close() diff --git a/decrypt-db.sh b/legacy/decrypt-db.sh similarity index 91% rename from decrypt-db.sh rename to legacy/decrypt-db.sh index 35492aa..49c7860 100755 --- a/decrypt-db.sh +++ b/legacy/decrypt-db.sh @@ -32,11 +32,13 @@ echo "Use $version sqlcipher of $os." echo "Dump decrypted database... (Don't worry about libcrypt.so version warning.)" -SQLCIPHER=./third-party/sqlcipher/$os/$version +SQLCIPHER=./sqlcipher/$os/$version export LD_LIBRARY_PATH=$SQLCIPHER "$SQLCIPHER"/sqlcipher "$MSGDB" << EOF PRAGMA key='$KEY'; PRAGMA cipher_use_hmac = off; +PRAGMA cipher_page_size = 1024; +PRAGMA kdf_iter = 4000; ATTACH DATABASE "$output" AS db KEY ""; SELECT sqlcipher_export("db"); DETACH DATABASE db; diff --git a/third-party/sqlcipher/LICENSE b/legacy/sqlcipher/LICENSE similarity index 100% rename from third-party/sqlcipher/LICENSE rename to legacy/sqlcipher/LICENSE diff --git a/third-party/sqlcipher/README.md b/legacy/sqlcipher/README.md similarity index 100% rename from third-party/sqlcipher/README.md rename to legacy/sqlcipher/README.md diff --git a/third-party/sqlcipher/darwin/64bit/.libs/sqlite3 b/legacy/sqlcipher/darwin/64bit/.libs/sqlite3 similarity index 100% rename from third-party/sqlcipher/darwin/64bit/.libs/sqlite3 rename to legacy/sqlcipher/darwin/64bit/.libs/sqlite3 diff --git a/third-party/sqlcipher/darwin/64bit/sqlcipher b/legacy/sqlcipher/darwin/64bit/sqlcipher similarity index 100% rename from third-party/sqlcipher/darwin/64bit/sqlcipher rename to legacy/sqlcipher/darwin/64bit/sqlcipher diff --git a/third-party/sqlcipher/linux/32bit/libsqlcipher.so.0 b/legacy/sqlcipher/linux/32bit/libsqlcipher.so.0 similarity index 100% rename from third-party/sqlcipher/linux/32bit/libsqlcipher.so.0 rename to legacy/sqlcipher/linux/32bit/libsqlcipher.so.0 diff --git a/third-party/sqlcipher/linux/32bit/sqlcipher b/legacy/sqlcipher/linux/32bit/sqlcipher similarity index 100% rename from third-party/sqlcipher/linux/32bit/sqlcipher rename to legacy/sqlcipher/linux/32bit/sqlcipher diff --git a/third-party/sqlcipher/linux/64bit/libsqlcipher.so.0 b/legacy/sqlcipher/linux/64bit/libsqlcipher.so.0 similarity index 100% rename from third-party/sqlcipher/linux/64bit/libsqlcipher.so.0 rename to legacy/sqlcipher/linux/64bit/libsqlcipher.so.0 diff --git a/third-party/sqlcipher/linux/64bit/sqlcipher b/legacy/sqlcipher/linux/64bit/sqlcipher similarity index 100% rename from third-party/sqlcipher/linux/64bit/sqlcipher rename to legacy/sqlcipher/linux/64bit/sqlcipher