Java批量解析微信dat文件,微信圖片破解

前言

關於異或值怎麼計算

代碼

第二種方式,適合不懂怎麼計算,想直接用的代碼

前言

偶然看到有可以解密微信dat的文檔,上網查了查,找到了一篇可以用的文章,不過轉換過程代碼是有問題的,在這裡改了下發布上來。

提取碼:ymw6

關於異或值怎麼計算

首先使用十六進制器打開微信dat文件,顯示如下

Java批量解析微信dat文件,微信圖片破解

jpg圖片文件頭一般為FF D8 開頭的,所以此處使用科學計算器,計算異或值

Java批量解析微信dat文件,微信圖片破解

Java批量解析微信dat文件,微信圖片破解

計算後的值

Java批量解析微信dat文件,微信圖片破解

所以此處異或值就是0x9D

代碼

以下是java代碼,創建一個weChatImgRevert .java後複製進去就好啦。

此處的jdk版本需要1.8以上…,另外三個參數需要改成自己的哦~

<code>package main.java.com.example.demo;

import

java.io.*;

import

java.util.Arrays;

import

java.util.HashMap;

import

java.util.Map;

import

java.util.concurrent.atomic.AtomicReference;

public

class

weChatImgRevert

{

public

static

void

main

(String[] args)

{ String path =

"C:\\Users\\Administrator\\Documents\\WeChat Files\\xxx\\FileStorage\\Image\\2019-07"

; String targetPath =

"D:\\weChat\\2019-07"

;

int

xor

=

0xCB

; convert(path, targetPath,

xor

); }

private

static

void

convert

(String path, String targetPath,

int

xor

)

{ File[] file =

new

File(path).listFiles();

if

(file == null) {

return

; }

int

size = file.length; System.out.println(

"總共"

+ size +

"個文件"

); AtomicReference integer =

new

AtomicReference<>(

0

); Arrays.stream(file).parallel().forEach(file1 -> {

try

(InputStream reader =

new

FileInputStream(file1); OutputStream writer =

new

FileOutputStream(targetPath + file1.getName().split(

"\\."

)[

0

] +

".jpg"

)) { byte[] bytes =

new

byte[

1024

*

10

];

int

b;

while

((b = reader.read(bytes)) !=

-1

) {

for

(

int

i =

0

; i < bytes.length; i++) { bytes[i] = (byte) (

int

) (bytes[i] ^

xor

);

if

(i == (b -

1

)) {

break

; } } writer.write(bytes,

0

, b); writer.flush(); } integer.

set

(integer.get() +

1

); System.out.println(file1.getName() +

"(大小:"

+ ((

double

) file1.length() /

1000

) +

"kb),進度:"

+ integer.get() +

"/"

+ size); }

catch

(Exception e) { e.printStackTrace(); } }); System.out.println(

"解析完畢!"

); }

private

static

int

getXor

(String PhotoPath)

{ File file =

new

File(PhotoPath);

try

(InputStream reader =

new

FileInputStream(file)) {

int

[] xors =

new

int

[

4

]; xors[

0

] = reader.read() &

0xFF

^

0xFF

; xors[

1

] = reader.read() &

0xFF

^

0xD8

; reader.skip(file.length() -

1

); xors[

2

] = reader.read() &

0xFF

^

0xFF

; xors[

3

] = reader.read() &

0xFF

^

0xD9

; Map

map

=

new

HashMap<>();

for

(

int

xor

: xors) {

if

(

map

.containsKey(

xor

)) {

map

.put(

xor

,

map

.get(

xor

) +

1

); }

else

{

map

.put(

xor

,

1

); } }

return

map

.values().stream().max(Integer::compareTo).get(); }

catch

(Exception e) { e.printStackTrace(); }

return

0

; } }/<code>

執行main方法後就可以在目標文件夾中去看轉換後的圖片了
以下是轉換後的效果圖片:

Java批量解析微信dat文件,微信圖片破解

第二種方式,適合不懂怎麼計算,想直接用的代碼

以下是java代碼,創建一個WxChatImgRevert.java後複製進去就好啦。

此處的jdk版本需要1.8以上…,另外兩個參數需要改成自己的哦~

此處的原理是判斷圖片文件的十六進制特徵碼。

<code>package main.java.com.example.demo;

import

java.io.*;

import

java.util.Arrays;

import

java.util.HashMap;

import

java.util.Map;

import

java.util.concurrent.atomic.AtomicInteger;

import

java.util.concurrent.atomic.AtomicReference;

public

class

WxChatImgRevert2 {

public

static

void

main(

String

[] args) {

String

path =

"C:\\Users\\Administrator\\Documents\\WeChat Files\\xxx\\FileStorage"

;

String

targetPath =

"D:\\weChat\\temp"

; convert(path, targetPath); }

private

static

void

convert(

String

path,

String

targetPath) { File[] file =

new

File(path).listFiles();

if

(file ==

null

) {

return

; } int size = file.length; System.out.println(

"總共"

+ size +

"個文件"

); AtomicReference integer =

new

AtomicReference<>(

0

); AtomicInteger x =

new

AtomicInteger();

for

(File file1 : file) {

if

(file1.isFile()) {

Object

[] xori = getXor(file1);

if

(xori !=

null

&& xori[

1

] !=

null

){ x.set((int)xori[

1

]); }

break

; } } Arrays.stream(file).parallel().forEach(file1 -> {

if

(file1.isDirectory()) {

String

[] newTargetPath = file1.getPath().split(

"/|\\"

); File targetFile =

new

File(targetPath+File.separator+newTargetPath[newTargetPath.length -

1

]);

if

(!targetFile.exists()) { targetFile.mkdirs(); } convert(file1.getPath(),targetPath+File.separator+newTargetPath[newTargetPath.length -

1

]);

return

; }

Object

[] xor = getXor(file1);

if

(x.get() ==

0

&& xor[

1

] !=

null

&& (int) xor[

1

] !=

0

) { x.set((int) xor[

1

]); } xor[

1

] = xor[

1

] ==

null

? x.get() : xor[

1

];

try

(InputStream reader =

new

FileInputStream(file1); OutputStream writer =

new

FileOutputStream(targetPath + File.separator + file1.getName().split(

"\\."

)[

0

] + (xor[

0

] !=

null

?

"."

+ xor[

0

] :

""

))) { byte[] bytes =

new

byte[

1024

*

10

]; int b;

while

((b = reader.read(bytes)) !=

-1

) {

for

(int i =

0

; i < bytes.length; i++) { bytes[i] = (byte) (int) (bytes[i] ^ (int) xor[

1

]);

if

(i == (b -

1

)) {

break

; } } writer.write(bytes,

0

, b); writer.flush(); } integer.set(integer.get() +

1

); System.out.println(file1.getName() +

"(大小:"

+ ((double) file1.length() /

1000

) +

"kb,異或值:"

+ xor[

1

] +

"),"

+

"進度:"

+ integer.get() +

"/"

+ size); }

catch

(Exception e) { e.printStackTrace(); } }); System.out.println(

"解析完畢!"

); }

private

static

Object

[] getXor(File file) {

Object

[] xor =

null

;

if

(file !=

null

) { byte[] bytes =

new

byte[

4

];

try

(InputStream reader =

new

FileInputStream(file)) { reader.read(bytes,

0

, bytes.length); }

catch

(Exception e) { e.printStackTrace(); } xor = getXor(bytes); }

return

xor; }

private

static

Object

[] getXor(byte[] bytes) {

Object

[] xorType =

new

Object

[

2

]; int[] xors =

new

int[

3

];

for

(Map.Entry<

String

,

String

>

type

: FILE_TYPE_MAP.entrySet()) {

String

[] hex = {

String

.valueOf(

type

.getKey().charAt(

0

)) +

type

.getKey().charAt(

1

),

String

.valueOf(

type

.getKey().charAt(

2

)) +

type

.getKey().charAt(

3

),

String

.valueOf(

type

.getKey().charAt(

4

)) +

type

.getKey().charAt(

5

) }; xors[

0

] = bytes[

0

] &

0xFF

^ Integer.parseInt(hex[

0

],

16

); xors[

1

] = bytes[

1

] &

0xFF

^ Integer.parseInt(hex[

1

],

16

); xors[

2

] = bytes[

2

] &

0xFF

^ Integer.parseInt(hex[

2

],

16

);

if

(xors[

0

] == xors[

1

] && xors[

1

] == xors[

2

]) { xorType[

0

] =

type

.getValue(); xorType[

1

] = xors[

0

];

break

; } }

return

xorType; }

private

final

static

Map<

String

,

String

> FILE_TYPE_MAP =

new

HashMap<

String

,

String

>();

static

{ getAllFileType(); }

private

static

void

getAllFileType() { FILE_TYPE_MAP.put(

"ffd8ffe000104a464946"

,

"jpg"

); FILE_TYPE_MAP.put(

"89504e470d0a1a0a0000"

,

"png"

); FILE_TYPE_MAP.put(

"47494638396126026f01"

,

"gif"

); FILE_TYPE_MAP.put(

"49492a00227105008037"

,

"tif"

); FILE_TYPE_MAP.put(

"424d228c010000000000"

,

"bmp"

); FILE_TYPE_MAP.put(

"424d8240090000000000"

,

"bmp"

); FILE_TYPE_MAP.put(

"424d8e1b030000000000"

,

"bmp"

); FILE_TYPE_MAP.put(

"41433130313500000000"

,

"dwg"

); FILE_TYPE_MAP.put(

"3c21444f435459504520"

,

"html"

); FILE_TYPE_MAP.put(

"3c21646f637479706520"

,

"htm"

); FILE_TYPE_MAP.put(

"48544d4c207b0d0a0942"

,

"css"

); FILE_TYPE_MAP.put(

"696b2e71623d696b2e71"

,

"js"

); FILE_TYPE_MAP.put(

"7b5c727466315c616e73"

,

"rtf"

); FILE_TYPE_MAP.put(

"38425053000100000000"

,

"psd"

); FILE_TYPE_MAP.put(

"46726f6d3a203d3f6762"

,

"eml"

); FILE_TYPE_MAP.put(

"d0cf11e0a1b11ae10000"

,

"doc"

); FILE_TYPE_MAP.put(

"d0cf11e0a1b11ae10000"

,

"vsd"

); FILE_TYPE_MAP.put(

"5374616E64617264204A"

,

"mdb"

); FILE_TYPE_MAP.put(

"252150532D41646F6265"

,

"ps"

); FILE_TYPE_MAP.put(

"255044462d312e360d25"

,

"pdf"

); FILE_TYPE_MAP.put(

"2e524d46000000120001"

,

"rmvb"

); FILE_TYPE_MAP.put(

"464c5601050000000900"

,

"flv"

); FILE_TYPE_MAP.put(

"00000020667479706973"

,

"mp4"

); FILE_TYPE_MAP.put(

"49443303000000000f76"

,

"mp3"

); FILE_TYPE_MAP.put(

"000001ba210001000180"

,

"mpg"

); FILE_TYPE_MAP.put(

"3026b2758e66cf11a6d9"

,

"wmv"

); FILE_TYPE_MAP.put(

"524946464694c9015741"

,

"wav"

); FILE_TYPE_MAP.put(

"52494646d07d60074156"

,

"avi"

); FILE_TYPE_MAP.put(

"4d546864000000060001"

,

"mid"

); FILE_TYPE_MAP.put(

"504b0304140000000800"

,

"zip"

); FILE_TYPE_MAP.put(

"526172211a0700cf9073"

,

"rar"

); FILE_TYPE_MAP.put(

"235468697320636f6e66"

,

"ini"

); FILE_TYPE_MAP.put(

"504b03040a0000000000"

,

"jar"

); FILE_TYPE_MAP.put(

"4d5a9000030000000400"

,

"exe"

); FILE_TYPE_MAP.put(

"3c25402070616765206c"

,

"jsp"

); FILE_TYPE_MAP.put(

"4d616e69666573742d56"

,

"mf"

); FILE_TYPE_MAP.put(

"3c3f786d6c2076657273"

,

"xml"

); FILE_TYPE_MAP.put(

"efbbbf2f2a0d0a53514c"

,

"sql"

); FILE_TYPE_MAP.put(

"7061636b616765207765"

,

"java"

); FILE_TYPE_MAP.put(

"406563686f206f66660d"

,

"bat"

); FILE_TYPE_MAP.put(

"1f8b0800000000000000"

,

"gz"

); FILE_TYPE_MAP.put(

"6c6f67346a2e726f6f74"

,

"properties"

); FILE_TYPE_MAP.put(

"cafebabe0000002e0041"

,

"class"

); FILE_TYPE_MAP.put(

"49545346030000006000"

,

"chm"

); FILE_TYPE_MAP.put(

"04000000010000001300"

,

"mxp"

); FILE_TYPE_MAP.put(

"504b0304140006000800"

,

"docx"

); FILE_TYPE_MAP.put(

"d0cf11e0a1b11ae10000"

,

"wps"

); FILE_TYPE_MAP.put(

"6431303a637265617465"

,

"torrent"

); FILE_TYPE_MAP.put(

"494d4b48010100000200"

,

"264"

); FILE_TYPE_MAP.put(

"6D6F6F76"

,

"mov"

); FILE_TYPE_MAP.put(

"FF575043"

,

"wpd"

); FILE_TYPE_MAP.put(

"CFAD12FEC5FD746F"

,

"dbx"

); FILE_TYPE_MAP.put(

"2142444E"

,

"pst"

); FILE_TYPE_MAP.put(

"AC9EBD8F"

,

"qdf"

); FILE_TYPE_MAP.put(

"E3828596"

,

"pwl"

); FILE_TYPE_MAP.put(

"2E7261FD"

,

"ram"

); } }/<code>

簡要介紹下小工具:
打開小工具後的頁面是這樣子的,如果沒有安裝jdk8的話,可以在這裡下載安裝,不然是運行不了的

Java批量解析微信dat文件,微信圖片破解

微信的數據存儲地址一般是:C:\Users\Administrator\Documents\WeChat Files\xxx

可以整個扔進去,但是要注意,輸出地址一定不能和存儲地址相同,最好不要在同一個文件夾裡面!!!

本質上,第一個是讀取操作,第二個是寫入操作,讀取並不會破壞原文件,但是寫入如果是同一個文件夾,並且存在同名文件,會被覆蓋掉。轉換後就是在你指定的輸出目錄裡面

Java批量解析微信dat文件,微信圖片破解

s:小工具是花了一晚上隨手寫的,樓主估計都找不到源碼在哪裡了,所以將就著用吧。


分享到:


相關文章: