网上看到有dat文件破解的,不过都是java和python的,没看到有JS的
自己有了些兴致,所以打算用JS实现。平台是Node
本文按照流程来讲,方便大家理解。如果直接想要实现的代码,请拉到最后。
微信的dat图片文件在xxxx/FileStorage/Image目录下
先要查看加密的dat文件。直接打开肯定是不行的,因为里面是二进制数据,所以需要一个十六进制器打开。
如果用的是VS Code ,那就很方便了,直接ctrl + shift + x 打开插件商店搜索 hexdump for VSCode,用这个插件可以在VSCode上面很方便地查看文件的十六进制码:
然后用VScode打开文件,在文件上右键选择 Show Hexdump 就可以查看十六进制:
微信的dat文件是如何加密的?原理很简单:是把文件内容通过某个数值进行异或操作来进行加密的,所以我们必须要计算出它的异或值。
JPG图片文件的开头都是 FF D8 FF E0 00 10 4A 46 49 46 所以我们可以先用FF D8 FF 先测试计算。(大部分的文件都是jpg的,当然也有少部分存在png文件,可以多试几个dat文件)
当然不用自己计算,我们打开WIN10自带的计算器,切换到程序员模式进行十六进制的异或运算
刚才十六进制打开的文件开头是5B 7C 5B ,所以让5B 7C 5B 和FF D8 FF进行异或运算就好了:
得出结果是A4 A4 A4 显而易见,异或值是A4(hex) 也就是说可以通过异或值和dat文件解密得到原文件了
每个人的异或值可能不一样
// 拖拽添加文件drop (e) {
const fileList = e.dataTransfer.files
if (!fileList) return
// 取文件后缀名,必须是dat文件
let taskList = []
let indexList = []
for (let i = 0; i < fileList.length; i++) {
const file = fileList[i]
if (!/.dat$/i.test(file.name)) {
return this.$toast('请选择DAT文件!')
}
let fStat = fs.statSync(file.path)
if (fStat.isDirectory()) {
return this.$toast('请选择DAT文件!')
}
taskList.push(this.getFileInfo(file.path))
indexList.push(i)
}
Promise.all(taskList).then((infos) => {
if (!infos || !infos.length) return
infos.forEach((v, i) => {
let file = fileList[indexList[i]]
this.filesList.push({
name: file.name, path: file.path, size: file.size, ...v
})
})
})
}
// 获取单个文件的信息(包括密码和数据解密)getFileInfo (filePath) {
let result = {name: '', type: '未知', password: '', data: '', url: ''}
let _arr = path.basename(filePath).split('.')
result.name = _arr.slice(0, _arr.length - 1).join('.')
return new Promise((resolve, reject) => {
if (!fs.existsSync(filePath)) {
reject('文件不存在')
}
fs.readFile(filePath, (err, data) => {
if (err || !data) reject('读取文件错误')
result.data = data
for (let key in this.fileHeaderMarks) {
let val = this.fileHeaderMarks[key] || []
let pwd1 = (val[0] || 0) ^ data[0]
let pwd2 = (val[1] || 0) ^ data[1]
if (pwd1 === pwd2) {
result.type = key
result.password = pwd1
break
}
}
if (result.password) {
let mimeType = this.fileMimeType[result.type] || `image/${result.type}`
result.data = result.data.map(v => (v ^ result.password))
result.url = `data:${mimeType};base64,${result.data.toString('base64')}`
}
resolve(result)
})
})
}
Web版工具源码:https://pan.baidu.com/s/1_KIqd0h_3T2vcR87GlUJYg?pwd=3m4h 提取码: 3m4h