侧边栏壁纸
博主头像
itachi博主等级

我一路向北,离开有你的季节

  • 累计撰写 10 篇文章
  • 累计创建 8 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Java解析微信dat文件

itachi
2023-08-03 / 0 评论 / 0 点赞 / 428 阅读 / 1,709 字
温馨提示:
本文最后更新于 2023-08-22,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

java批量解析微信dat文件
1.WxChatImgRevert2.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.JTextArea;

public class WxChatImgRevert2 {
  public static void convert(String path, String targetPath, JTextArea area) {
    File file = new File(path);
    if (file.isFile())
      parseFile(file, targetPath, new AtomicInteger(0), new AtomicReference<>(Integer.valueOf(1)), 1, area);
    File[] files = file.listFiles();
    if (files == null)
      return;
    int size = files.length;
    System.out.println(\"总共\"+ size + \"个文件\");
    AtomicReference<Integer> integer = new AtomicReference<>(Integer.valueOf(0));
    AtomicInteger x = new AtomicInteger();
    for (File file1 : files) {
      if (file1.isFile()) {
        Object[] xori = getXor(file1);
        if (xori != null && xori[1] != null)
          x.set(((Integer)xori[1]).intValue());
        break;
      }
    }
    File targetFile = new File(targetPath);
    if (!targetFile.exists())
      targetFile.mkdirs();
    Arrays.<File>stream(files).parallel().forEach(file1 -> parseFile(file1, targetPath, x, integer, size, area));
    area.append(\"\\n解析完毕\");
    System.out.println(\"解析完毕\");
  }

  private static void parseFile(File file1, String targetPath, AtomicInteger x, AtomicReference<Integer> integer, int size, JTextArea area) {
    if (file1.isDirectory()) {
      String[] newTargetPath = file1.getPath().split(\"/|\\\\\\\\\");
      File targetFile1 = new File(targetPath + File.separator + newTargetPath[newTargetPath.length - 1]);
      if (!targetFile1.exists())
        targetFile1.mkdirs();
      convert(file1.getPath(), targetPath + File.separator + newTargetPath[newTargetPath.length - 1], area);
      return;
    }
    Object[] xor = getXor(file1);
    if (x.get() == 0 && xor[1] != null && ((Integer)xor[1]).intValue() != 0)
      x.set(((Integer)xor[1]).intValue());
    xor[1] = (xor[1] == null) ? Integer.valueOf(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[10240];
      int b;
      while ((b = reader.read(bytes)) != -1) {
        for (int i = 0; i < bytes.length; i++) {
          bytes[i] = (byte)(bytes[i] ^ ((Integer)xor[1]).intValue());
          if (i == b - 1)
            break;
        }
        writer.write(bytes, 0, b);
        writer.flush();
      }
      integer.set(Integer.valueOf(((Integer)integer.get()).intValue() + 1));
      area.append(\"\\n\" + file1.getName() + \"大小(\"+ (file1.length() / 1000.0D) + \"kb,异或值\"+ xor[1] + \"),进度\" + integer.get() + \"/\" + size);
      System.out.println(file1.getName() + \"大小(\"+ (file1.length() / 1000.0D) + \"kb,异或值\"+ xor[1] + \"),进度\" + integer.get() + \"/\" + size);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  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(((String)type.getKey()).charAt(0)) + ((String)type.getKey()).charAt(1), String.valueOf(((String)type.getKey()).charAt(2)) + ((String)type.getKey()).charAt(3), String.valueOf(((String)type.getKey()).charAt(4)) + ((String)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] = Integer.valueOf(xors[0]);
        break;
      }
    }
    return xorType;
  }

  private static final Map<String, String> FILE_TYPE_MAP = new HashMap<>();

  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(\"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(\"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\");
  }
}

2.window.java

import java.awt.Component;
import java.awt.LayoutManager;
import java.awt.Point;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class window {
  public static void main(String[] args) {
    JFrame frame = new JFrame(\"微信加密图片\");
    frame.setResizable(false);
    frame.setSize(540, 525);
    frame.setLocationRelativeTo((Component)null);
    frame.setDefaultCloseOperation(3);
    JPanel panel = new JPanel();
    placeComponents(panel);
    frame.add(panel);
    frame.setVisible(true);
  }

  private static void placeComponents(JPanel panel) {
    panel.setLayout((LayoutManager)null);
    JLabel wxLabel = new JLabel(\"微信数据存储地址\");
    wxLabel.setBounds(10, 20, 120, 25);
    JTextField wxText = new JTextField(20);
    wxText.setBounds(130, 20, 300, 25);
    JButton wxButton = new JButton(\"浏览\");
    wxButton.setBounds(440, 20, 80, 25);
    wxButton.addActionListener(e -> openChoose(wxText));
    JLabel outLabel = new JLabel(\"输出地址\");
    outLabel.setBounds(10, 50, 120, 25);
    panel.add(outLabel);
    JTextField outText = new JTextField(20);
    outText.setBounds(130, 50, 300, 25);
    JLabel outlabel = new JLabel(\"输出日志\");
    outlabel.setBounds(10, 120, 120, 25);
    JButton outButton = new JButton(\"浏览\");
    outButton.setBounds(440, 50, 80, 25);
    outButton.addActionListener(e -> openChoose(outText));
    JTextArea textArea = new JTextArea();
    textArea.setLineWrap(true);
    textArea.setAutoscrolls(true);
    textArea.setEditable(false);
    JScrollPane jScrollPane = new JScrollPane(textArea);
    jScrollPane.setHorizontalScrollBarPolicy(30);
    jScrollPane.setVerticalScrollBarPolicy(20);
    jScrollPane.setBounds(10, 150, 515, 300);
    jScrollPane.setAutoscrolls(true);
    int height = 10;
    Point p = new Point();
    p.setLocation(0, textArea.getLineCount() * height);
    jScrollPane.getViewport().setViewPosition(p);
    JButton convertButton = new JButton(\"转换\");
    convertButton.setBounds(215, 90, 80, 25);
    convertButton.addActionListener(e -> {
          if (!(new File(wxText.getText())).exists()) {
            JOptionPane.showMessageDialog(panel, \"微信存储地址不存在\", \"警告\", 2);
            return;
          }
          WxChatImgRevert2.convert(wxText.getText(), outText.getText(), textArea);
          JOptionPane.showMessageDialog(panel, \"转换完成\", \"完成提示\", -1);
        });
    JButton exitButton = new JButton(\"退出\");
    exitButton.setBounds(215, 455, 80, 25);
    exitButton.addActionListener(e -> System.exit(0));
    panel.add(wxLabel);
    panel.add(wxText);
    panel.add(wxButton);
    panel.add(outText);
    panel.add(outlabel);
    panel.add(outButton);
    panel.add(jScrollPane);
    panel.add(convertButton);
    panel.add(exitButton);
  }

  private static void openChoose(JTextField textField) {
    JFileChooser wxChooser = new JFileChooser(textField.getText());
    wxChooser.setFileSelectionMode(2);
    int status = wxChooser.showOpenDialog(null);
    if (status != 1) {
      File file = wxChooser.getSelectedFile();
      textField.setText(file.getPath());
    }
  }
}

直接拷贝上面两个代码,在idea中粘贴就会创建对应文件,将两个java文件放到一起之后运行window.main之后就会打开程序
QQ截图20230803171902
然后选择自己微信聊天记录的位置和要输出的位置点击转换就可以了

忘记之前是从哪找到的了,如有侵权请联系本人,看到消息后会尽快处理

0

评论区