如何从WhatsApp的备份数据库中提取消息,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
我将为大家介绍如何使用Python从WhatsApp恢复消息。并且我会着重解释如何从WhatsApp的sqlite数据库中查找和提取对话,并解析那里的字段和数据。这绝不是一项全面的逆向/取证分析的工作 – 我写这篇文章的唯一原因是,目前我并没有找到一个你可以信任的可用于此目的免费信息和/或开源工具。所以我想如果我能分享我所做的工作,那么将可以为他人节省一些时间。你可以使用与之相似的过程来分析其他的(messaging)应用程序。
我将使用Jupyter Notebooks和Pandas,但几乎所有代码都可以独立于Jupyter使用。用于从WhatsApp sqlite DB中提取消息的代码(专为Jupyter notebook编写),你可以在github获取到。
背景
由于房地产开发商的一些法律问题(有诚实的开发商吗?)我需要从一个放在壁橱里两年的旧iPhone设备中恢复whatsApp信息。
我不是正常的iPhone用户,所以我开始想办法来做到这一点,我发现iCloud并没有赋予访问实际备份内容的权限。不过这里有一些工具可以帮助你获取登录凭证,并允许你浏览完整的备份内容,但是我不想将我(妻子)的登录凭证透露给这些未知工具。所以,我开始研究如何在不损害帐户安全的前提下做到这一点。
为iPhone充电开机后我发现WhatsApp无法正常工作,并出现了一个奇怪的消息提示Your phone date is inaccurate! Adjust your clock and try again(你的电话日期不准确!请调整你的时钟并再次尝试)。我不知道日期问题与启动WhatsApp有什么关系,但修复日期和时间并没有解决这个问题,我阅读了许多网上的解决方案似乎都是建议卸载重装。但我不想冒这个险,因为在法庭上我需要这些信息作为证据。
第1步 – 从iPhone备份和解压缩文件
此步骤更适用于Mac OS,尽管它在其他操作系统的工作方式类似。
1.创建虚拟机并在上面安装iTunes。确保VM未连接到网络。(如果你不知道如何创建VM,请参阅本文)。
2.将iPhone连接到VM。按照通常的步骤在VM上本地备份iPhone。对于那些对Mac感兴趣的人,可以在该位置找到备份:~/Library/Application Support/MobileSync/Backup
备份格式描述请参阅此处。
3.在虚拟机中安装iPhone备份提取工具(如iExplorer by Macroplant)。哪种工具不重要,因为它无法访问互联网,因此你的数据是安全的。
4.最后使用备份提取工具提取chatstorage.sqlite,这是主要的whatsapp会话数据库。要访问它你需要浏览到“App Group”→“group.net.whatsapp.WhatsApp.shared”
5.另外,你还可以通过提取文件夹来提取media:“App” → “net.whatsapp.WhatsApp” → “Library” → “Media”
第2步 – 连接到数据库并阅读消息表
WhatsApp似乎将所有对话存储在了Sqlite DB中。作为第一步,让我们尝试使用sqlite3内置的python库+Pandas来查看我们是否可以连接到数据库并获取表的列:
如你所见,有18张表。通过仔细观察其中一个表引起了我的注意(即带有你的消息的那个)似乎是ZWAMESSAGE。让我们打开它:
可以看到该表中有34列:
让我们看看我们有什么。以下是我根据我在自己数据库中的表中找到的数据和我的推论进行的分析:
1. Z_PK — seems like a serial number 2. Z_ENT to ZFILTEREDRECIPIENTCOUNT — seem less important 3. ZFLAGS — seems to indicate message state 4. ZGROUPEVENTTYPE — seems to be related to group chats 5. ZISFROMME — message is from me… it is 1 for messages sent by this user and 0 for messages received 6. ZMESSAGEERRORSTATUS to ZSPOTLIGHTSTATUS — seems like general statuses 7. ZSTARRED — did we star the message 8. ZCHATSESSION — unique identifier denoting a chat session 9. ZGROUPMEMBER — haven’t gotten to look at this one yet 10. ZLASTSESSION — last chat session? didn’t dig into it 11. ZMEDIAITEM — seems related to media item indexing, might be an identifier to one of the other tables 12. ZMESSAGEINFO and ZPARENTMESSAGE — seem simple enough to figure out from the names 13. ZMESSAGEDATE — message creation date probably (see date format discussion below) 14. ZSENTDATE — message sent date probably (see date format discussion below) 15. ZFROMJID — from who did we get it (if it is an incoming message) 16. ZMEDIASECTIONID — seems related to media storage for media messages, doesn’t show in messages without media 17. ZPHASH - hmmm... not sure 18. ZPUSHNAME — seems like the contact name on your phone 19. ZSTANZAID — some conversation / media id indicator. Format seems different in media messages and text messages 20. ZTEXT — message text 21. ZTOJID — to whom did we send it (if it is an outgoing message)
第3步 – 提取特定的对话
我们的基本目标是提取特定的对话或通信。因此,如果我们记住部分文本,我们可以按姓名或电话号码搜索联系人,或者按消息搜索特定的对话,最终根据会话ID提取完整的对话。
但是,在我们做这些之前,我们应该先弄清楚如何将日期和时间转换成人类可读的格式。直觉上我假设zmessagedate是一个unix时间戳。所以我把它转换成一个日期,这就是我得到的结果:
苹果似乎以其无限独特的智慧决定在iPhone上使用从1.1.2001开始的日期,所以让我们看看如果我们将unix-time time0的偏移量添加到1.1.2001,会发生什么情况:
这似乎解决了这个问题。在此过程中,我还向data-frame添加了一个日期索引,使其更易于使用。请注意,如果你从Android或其他操作系统导入,则可能不需要使用此日期转换。
日期有了,现在我们可以开始提取对话了。首先,让我们提取一个我们关心的对话,比如一个特定的号码:
你应该注意到我创建的lambda用于搜索列。这里有一个让人失望的Python “Wat” moment ,因为False | None != None | False这是不合理的。无论如何,继续看ZCHATSESSION列,我们会注意到在我的例子中,这个号码的会话ID将是“104.0”(如果还有群组聊天,你可能会看到多个聊天会话ID)。所以下一步将是提取聊天会话中的所有消息。为此,让我们为它和上面提到的其他搜索方法添加适当的访问器(accessors):
现在,让我们从聊天会话中获取所有消息并显示它们(启用多行格式以查看所有文本):
第4部分 – 结束语及media提取的注意事项
媒体文件被存储在步骤1中提到的文件夹中,子文件夹基于共享文件的联系人的电话号码(以及表示组聊天的后缀?- 这是一个猜测)。每个电话号码下的子文件夹似乎遵循与iTunes备份格式类似的逻辑,我怀疑消息表引用了媒体表中的链接,但我没有花时间去实际验证。最后一点要注意的是,一些文件夹还将包含一些thumb文件,这些文件实际上只是JPG文件(重命名即可正常打开)。
Jupyter notebook的代码可以在Github上找到
我已从中删除了个人信息,但代码和示例完全相同。此外,notebook可能还包含了一些额外的信息。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/222926.html