1、首先在电脑上打开iTunes软件,点击左上角的“手机”图标。
2、选择“本电脑”,然后点击“立即备份”,备份完成后拔除手机并关闭iTunes软件。
3、在电脑上下载并打开“楼月免费iTunes备份管理器”,双击打开可以看到备份数据。
4、点击左侧的“微信聊天记录”,把“Documents”导出到电脑上。
5、接着点击“文件”,选择“恢复已删除的微信聊天记录”即可。
理论上是可以的,因为这个系统的话主要就是用来采取一些网络的信息,只要是通过互联网来传输储存的正常情况都是可以爬取到的,但是需要一定的编程能力才行。
导出微信聊天db文件
手机端导出
发现现在的Android手机都很难root,而db文件肯定在微信的应用目录下。拿不出来的。
电脑端导出(mac)
从~/Library/Containers/com.tencent.xinWeChat/Data/Library/Application\ Support/com.tencent.xinWeChat下找到对应账号的数据存储目录。
屏幕快照 2019-10-17 下午5.46.38.png
Message
存储聊天消息
Contact
存储联系人信息
获取db密钥
打开微信
命令行运行 lldb -p $(pgrep WeChat)
在 lldb 中输入 br set -n sqlite3_key, 回车
还是在 lldb 中,输入 c, 回车
扫码登录微信
这时候回到 lldb 界面, 输入 memory read --size 1 --format x --count 32 $rsi, 回车
命令行回显结果
0x000000000000: 0xab 0xcd 0xef 0xab 0xcd 0xef 0xab 0xcd
0x000000000008: 0xab 0xcd 0xef 0xab 0xcd 0xef 0xab 0xcd
0x000000000010: 0xab 0xcd 0xef 0xab 0xcd 0xef 0xab 0xcd
0x000000000018: 0xab 0xcd 0xef 0xab 0xcd 0xef 0xab 0xcd
忽略左边的地址( 0x000000000000: ,0x000000000008:),从左到右,从上到下,把形如 0xab 0xcd 的数据拼起来,然后去掉所有的 "0x"和空格、换行, 得到 64 个字符的字符串,这就是 微信数据库的 key
可以遇到的问题(来自网上,我在使用过程中没有这个问题))
*.db 文件要在另一台 PC 或 Mac 上 登录微信, 才能被关闭,否则里面的聊天记录不是最新的;当然也可以强制调用 wal_checkpoint, 不过作为土办法,在另一台电脑上登一下微信也无妨。
那么wal_checkpoint是什么?是一个sqlite命令,可以参考:,如果不想看英文,那就百度一下吧!
db browser for sqlite
db数据库可视化工具,打开需要查看的数据库文件:
屏幕快照 2019-10-17 下午6.43.43.png
先输入0x,然后把上面得到的密钥复制进来。由于编码的问题,可能复制进来会出现打不开的情况,你可以先把密钥复制到软件执行sql语句的地方,然后在复制。一会python读取db数据库会参考上面的设置参数。
python解密db数据库
这里需要使用sqlite来操作数据库,而sqlite本身是不支持加密和解密的,那么这部分就需要我们自己来完成,但是网上已经有开源库了。
使用到的python库
加密解密db库——pysqlcipher3。
加密算法库——sqlcipher。
微信db加密库——wcdb
参考文档
db解密
路径配置
# 加密DB文件绝对路径,微信DB加密方案参考:
DB_PATH = '/Users/pengdaosong/pds/python/PythonStudy/db/encryption/'
# 解密后生成不加密DB文件绝对路径
DB_OUT_PATH = '/Users/pengdaosong/pds/python/PythonStudy/db/decrypt/'
DB_OUT_JSON_PATH = '/Users/pengdaosong/pds/python/PythonStudy/db/json/'
DB_ROOT_PATH = '/Users/pengdaosong/pds/python/PythonStudy/db/'
# 解密数据库key
DB_KEY = "x''1133d3dd61764a9e80699b42b61e443515aeb00cf4f5497d9729adcb6c8e78e2''"
# 新的DB加密数据KEY,如果为空,者不加密
DB_NEW_KEY = ''
这里说一下DB_KEY的写法,官网写法是这样的:"x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";但是这样写始终是不能打开数据库的,始终报“不是一个数据库文件”。换成上面的写法后可以打开。所以,这里如果不能打开,把这两种写都试一试。像在密钥前加'0x'等都可以试一试。
解密
import pysqlcipher3.dbapi2 as sqliteimport config as cfdef decrypt(path, fileName):
# ———————————————————————————————————数据库操作———————————————————————————————————
# 参考:
# 连接数据库如果文件不存在,会自动在当前目录创建:
db = sqlite.connect(path + fileName)
# 创建一个Cursor:
db_cursor = db.cursor()
# ————————————————————————————————————解密数据DB———————————————————————————————————
# sqlcipher加密解密参考:
# sqlcipher开源库地址:
# sqlcipherApi:
db_cursor.execute("PRAGMA key='" + cf.DB_KEY + "';")
db_cursor.execute("PRAGMA cipher_compatibility=3;")
db_cursor.execute("PRAGMA cipher_page_size=1024;")
db_cursor.execute("PRAGMA kdf_iter=64000;")
db_cursor.execute("PRAGMA cipher_hmac_algorithm=HMAC_SHA1;")
db_cursor.execute("PRAGMA cipher_kdf_algorithm=PBKDF2_HMAC_SHA1;")
# 将解密文件导入新的DB文件
decrypt = cf.DB_OUT_PATH + 'decrypt_' + fileName
db_cursor.execute("ATTACH DATABASE '" + decrypt + "' AS db_de KEY '" + cf.DB_NEW_KEY + "'; -- empty key will disable encryption")
db_cursor.execute("SELECT sqlcipher_export('db_de');")
db_cursor.execute("DETACH DATABASE db_de;")
db_cursor.close()
更多加密参数设置参考:sqlcipher使用文档
将数据库导出为json
import pysqlcipher3.dbapi2 as sqliteimport config as cf_wximport dbToJsondef parse(path, fileName):
db = sqlite.connect(path + fileName)
db_cursor = db.cursor()
all_table = db_cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table';").fetchall()
print(all_table)
for x in all_table:
table_name = x[0]
print("Searching", table_name)
try:
t = db_cursor.execute('SELECT * FROM ' + table_name + ';')
dbToJson.tableToFile(db_cursor,table_name)
print('\n')
except BaseException as e:
print(e)
continue
db_cursor.close()
db.close()
import jsonimport numpy as npimport config as cf_wxclass MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.ndarray):
return obj.tolist()
elif isinstance(obj, bytes):
# utf-8会报错:'utf-8' codec can't decode byte 0xfc in position 14: invalid start byte
return str(obj, encoding='ISO-8859-15')
return json.JSONEncoder.default(self, obj)def tableToJson(cursor, table):
query = 'SELECT * FROM ' + table
rows = cursor.execute(query)
items = []
for row in rows:
item = {}
for key in cursor.description:
item.update({key[0]: value for value in row})
items.append(item)
# 注意不要写道for里面了,不然数据结果不对
js = json.dumps(items, ensure_ascii=False, cls=MyEncoder, indent=4)
print(js)
print('--------------------------------')def tableToFile(cursor, table):
query = 'SELECT * FROM ' + table
rows = cursor.execute(query)
items = []
for row in rows:
item = {}
# 参考:
for idx, col in enumerate(cursor.description):
value = row[idx]
item.update({col[0]: value})
items.append(item)
# 注意不要写道for里面了,不然数据结果不对
json_name = ""
if(table.endswith('.db')):
json_name = table[:(table.__len__ - 3)]
else:
json_name = table file = open(cf_wx.DB_OUT_JSON_PATH + json_name + ".json", 'w+')
# ensure_ascii默认为True,汉字会被编码成'\u4e00\u6839\u806a'
js = json.dumps(items, ensure_ascii=False, cls=MyEncoder, indent=4)
file.write(js)
file.close()
关联
查看聊天消息数据发现,不能把聊天消息数据表和对应的聊天人对应起来,因为消息表并没有存是和谁在聊天。如果不能和对应的人联系起来,岂不是感觉很不好。那这里就要用到联系人数据库了,密钥和上面的一样。打开联系人的数据查看:
屏幕快照 2019-10-17 下午7.30.41.png
这是其中一个联系人,将"m_nsUsrName"进行32 MD5后得到32为字符串。在者字符串前面加上"Chat_"就是这个联系人在消息数据库里面对应的表名。这样就可以通过这个字符串在消息数据库里找到对应的聊天消息了。
msn的聊天记录能保存多久? 你一旦选择了保存,就永远保存在你电脑的指定目录下了。当然要注意,如果你与某人的对话较多,当系统提示你谈话记录文件大小达到上限时,你一定要选择将先前的记录另外保存,否则记录...
怎么样恢复已删除的聊天记录? 聊天记录恢复器 自媒体以微信为例:1.电脑备份恢复,打开微信,点击左下角更多,点击备份与恢复,点击恢复聊天记录至手机,勾选需要恢复的微信聊天记录,点击确定,在手机上确认,...
内马尔晒与多纳鲁马聊天记录,都透露出了哪些信息? 1、这个聊天记录表示内马尔和多纳鲁马没有任何问题。在聊天记录中,多纳鲁马首先把记者的新闻发给了内马尔,同时也对内马尔道歉。内马尔表示大家不要去信那些不...
梦见银行卡里的钱被黑客刷走 从心理学的相关解说来看,许多梦境与现实之中相近或相反,多数来自於生活中的感动或特别强烈的记忆,因此这显现出做梦者本身对於自己潜意识中的繁琐事务有所紧张,或许来自於现实裏面的...
怎样才能把微信里聊天记录的头像和人名遮住 一、两种方法,一种马赛克,一种涂鸦。一般手机自带的相册都有这种功能。二、把微信里聊天记录的头像和人名遮住的方法:1、在微信界面把要遮住的图像和人名截图。2、打...
求一部关于包青天的电视剧 《七侠五义》之包公斗法王 从楼主的描述“展绍好像受伤快死了,好像被一个女子救了”恩,是七侠五义之包公斗法王,剧中展昭被法王贺连鹏打成重伤,几乎快死了......被法王的师妹欧...