From 03074e75a365ea2c6451f10157b461299463d89f Mon Sep 17 00:00:00 2001 From: Suxue Date: Tue, 26 Sep 2023 14:19:30 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=B7=A5=E4=BD=9C=E5=8C=BA?= =?UTF-8?q?=EF=BC=8C=E7=90=86=E9=A1=BA=E5=B7=A5=E4=BD=9C=E5=8C=BA=E6=A6=82?= =?UTF-8?q?=E5=BF=B5=E3=80=82=20=E6=96=B0=E5=A2=9E=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=A4=9A=E5=BC=80=E5=BE=AE=E4=BF=A1=E6=97=B6=E4=B9=9F=E8=83=BD?= =?UTF-8?q?=E6=96=B9=E4=BE=BF=E9=80=89=E6=8B=A9=E5=88=9B=E5=BB=BA/?= =?UTF-8?q?=E8=A7=A3=E5=AF=86=E3=80=82=20UI=E6=9B=B4=E6=96=B0=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E8=B4=B4=E5=90=88=E7=8E=B0=E5=9C=A8=E7=9A=84=E6=83=B3?= =?UTF-8?q?=E6=B3=95=E5=92=8C=E6=A6=82=E5=BF=B5=EF=BC=8C=E6=9B=B4=E6=98=93?= =?UTF-8?q?=E4=BA=8E=E7=90=86=E8=A7=A3=E3=80=82=20=E6=B7=BB=E5=8A=A03.9.7.?= =?UTF-8?q?25=E7=89=88=E6=9C=AC=E4=BF=A1=E6=81=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.xaml | 2 +- Helpers/DecryptionHelper.cs | 106 ++++++++++++ Helpers/ProcessHelper.cs | 13 ++ Helpers/WechatDBHelper.cs | 6 +- HtmlExport.cs | 37 +++-- Interface/ExportInterface.cs | 3 +- Main.xaml | 38 +++++ Main.xaml.cs | 184 +++++++++++++++++++++ MainWindow.xaml | 36 ---- MainWindow.xaml.cs | 174 -------------------- Model/Common.cs | 6 + Model/WXModel.cs | 17 ++ README.md | 17 +- SelectWechat.xaml | 24 +++ SelectWechat.xaml.cs | 85 ++++++++++ Tools/handle64.exe | Bin 0 -> 416144 bytes WXReader.cs | 311 ----------------------------------- WXUserReader.cs | 229 ++++++++++++++++++++++++++ WXWorkspace.cs | 125 ++++++++++++++ WechatPCMsgBakTool.csproj | 3 + version.json | 3 + 21 files changed, 874 insertions(+), 545 deletions(-) create mode 100644 Main.xaml create mode 100644 Main.xaml.cs delete mode 100644 MainWindow.xaml delete mode 100644 MainWindow.xaml.cs create mode 100644 SelectWechat.xaml create mode 100644 SelectWechat.xaml.cs create mode 100644 Tools/handle64.exe delete mode 100644 WXReader.cs create mode 100644 WXUserReader.cs create mode 100644 WXWorkspace.cs diff --git a/App.xaml b/App.xaml index 7d41d3c..f5efee3 100644 --- a/App.xaml +++ b/App.xaml @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WechatPCMsgBakTool" - StartupUri="MainWindow.xaml"> + StartupUri="Main.xaml"> diff --git a/Helpers/DecryptionHelper.cs b/Helpers/DecryptionHelper.cs index 6d1cb58..5b0f14a 100644 --- a/Helpers/DecryptionHelper.cs +++ b/Helpers/DecryptionHelper.cs @@ -151,6 +151,112 @@ private static string BytesToHex(byte[] bytes) { return BitConverter.ToString(bytes, 0).Replace("-", string.Empty).ToLower().ToUpper(); } + public static byte[] DecImage(string source) + { + //读取数据 + byte[] fileBytes = File.ReadAllBytes(source); + //算差异转换 + byte key = GetImgKey(fileBytes); + fileBytes = ConvertData(fileBytes, key); + return fileBytes; + } + public static string CheckFileType(byte[] data) + { + switch (data[0]) + { + case 0XFF: //byte[] jpg = new byte[] { 0xFF, 0xD8, 0xFF }; + { + if (data[1] == 0xD8 && data[2] == 0xFF) + { + return ".jpg"; + } + break; + } + case 0x89: //byte[] png = new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; + { + if (data[1] == 0x50 && data[2] == 0x4E && data[7] == 0x0A) + { + return ".png"; + } + break; + } + case 0x42: //byte[] bmp = new byte[] { 0x42, 0x4D }; + { + if (data[1] == 0X4D) + { + return ".bmp"; + } + break; + } + case 0x47: //byte[] gif = new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39(0x37), 0x61 }; + { + if (data[1] == 0x49 && data[2] == 0x46 && data[3] == 0x38 && data[5] == 0x61) + { + return ".gif"; + } + break; + } + case 0x49: // byte[] tif = new byte[] { 0x49, 0x49, 0x2A, 0x00 }; + { + if (data[1] == 0x49 && data[2] == 0x2A && data[3] == 0x00) + { + return ".tif"; + } + break; + } + case 0x4D: //byte[] tif = new byte[] { 0x4D, 0x4D, 0x2A, 0x00 }; + { + if (data[1] == 0x4D && data[2] == 0x2A && data[3] == 0x00) + { + return ".tif"; + } + break; + } + } + + return ".dat"; + } + private static byte GetImgKey(byte[] fileRaw) + { + byte[] raw = new byte[8]; + for (int i = 0; i < 8; i++) + { + raw[i] = fileRaw[i]; + } + + for (byte key = 0x01; key < 0xFF; key++) + { + byte[] buf = new byte[8]; + raw.CopyTo(buf, 0); + + if (CheckFileType(ConvertData(buf, key)) != ".dat") + { + return key; + } + } + return 0x00; + } + private static byte[] ConvertData(byte[] data, byte key) + { + for (int i = 0; i < data.Length; i++) + { + data[i] ^= key; + } + + return data; + } + public static string SaveDecImage(byte[] fileRaw,string source,string to_dir,string type) + { + FileInfo fileInfo = new FileInfo(source); + string fileName = fileInfo.Name.Substring(0, fileInfo.Name.Length - 4); + string saveFilePath = Path.Combine(to_dir, fileName + type); + using (FileStream fileStream = File.OpenWrite(saveFilePath)) + { + fileStream.Write(fileRaw, 0, fileRaw.Length); + fileStream.Flush(); + } + return saveFilePath; + } } } diff --git a/Helpers/ProcessHelper.cs b/Helpers/ProcessHelper.cs index 39bee76..c9d6d85 100644 --- a/Helpers/ProcessHelper.cs +++ b/Helpers/ProcessHelper.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; +using System.Windows; namespace WechatPCMsgBakTool.Helpers { @@ -15,6 +16,18 @@ public class ProcessHelper Process[] processes = Process.GetProcessesByName(ProcessName); if (processes.Length == 0) return null; + else if(processes.Length > 1) { + SelectWechat selectWechat = new SelectWechat(); + MessageBox.Show("检测到有多个微信,请选择本工作区对应的微信"); + selectWechat.ShowDialog(); + if (selectWechat.SelectProcess == null) + return null; + + Process? p = processes.ToList().Find(x => x.Id.ToString() == selectWechat.SelectProcess.ProcessId); + if (p == null) + return null; + return p; + } else return processes[0]; } diff --git a/Helpers/WechatDBHelper.cs b/Helpers/WechatDBHelper.cs index f0e992c..07bfaba 100644 --- a/Helpers/WechatDBHelper.cs +++ b/Helpers/WechatDBHelper.cs @@ -136,10 +136,10 @@ public static string MoveUserData(string path) } return "请复制目录至文本框内"; } - public static void DecryUserData(byte[] key) + public static void DecryUserData(byte[] key,string source,string to) { - string dbPath = Path.Combine(UserWorkPath, "DB"); - string decPath = Path.Combine(UserWorkPath, "DecDB"); + string dbPath = source; + string decPath = to; if(!Directory.Exists(decPath)) Directory.CreateDirectory(decPath); diff --git a/HtmlExport.cs b/HtmlExport.cs index 61205d5..55d946c 100644 --- a/HtmlExport.cs +++ b/HtmlExport.cs @@ -22,6 +22,14 @@ public void InitTemplate(WXSession session) HtmlBody += string.Format("

导出时间:{0}


", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); } + public void InitTemplate(WXContact contact) + { + WXSession session = new WXSession(); + session.NickName = contact.NickName; + session.UserName = contact.UserName; + InitTemplate(session); + } + public void Save(string path = "",bool append = false) { if (!append) @@ -41,21 +49,26 @@ public void SetEnd() HtmlBody += ""; } - public void SetMsg(WXReader reader, WXSession session) + public void SetMsg(WXUserReader reader,WXContact contact) { - List msgList = reader.GetMsgs(session.UserName); + if (Session == null) + throw new Exception("请初始化模版:Not Use InitTemplate"); + + List? msgList = reader.GetWXMsgs(contact.UserName); + if (msgList == null) + throw new Exception("获取消息失败,请确认数据库读取正常"); + msgList.Sort((x, y) => x.CreateTime.CompareTo(y.CreateTime)); + foreach (var msg in msgList) { - if (Session == null) - throw new Exception("请初始化模版:Not Use InitTemplate"); HtmlBody += string.Format("

{0} {1}

", msg.IsSender ? "我" : Session.NickName, TimeStampToDateTime(msg.CreateTime).ToString("yyyy-MM-dd HH:mm:ss")); if (msg.Type == 1) HtmlBody += string.Format("

{0}

", msg.StrContent); - else if(msg.Type == 3) + else if (msg.Type == 3) { - string? path = reader.GetImage(msg); + string? path = reader.GetAttachment(WXMsgType.Image, msg); if (path == null) { HtmlBody += string.Format("

{0}

", "图片转换出现错误或文件不存在"); @@ -63,9 +76,9 @@ public void SetMsg(WXReader reader, WXSession session) } HtmlBody += string.Format("

", path); } - else if(msg.Type == 43) + else if (msg.Type == 43) { - string? path = reader.GetVideo(msg); + string? path = reader.GetAttachment(WXMsgType.Video, msg); if (path == null) { HtmlBody += string.Format("

{0}

", "视频不存在"); @@ -73,12 +86,12 @@ public void SetMsg(WXReader reader, WXSession session) } HtmlBody += string.Format("

", path); } - else if(msg.Type == 34) + else if (msg.Type == 34) { - string? path = reader.GetVoice(msg); + string? path = reader.GetAttachment(WXMsgType.Audio, msg); if (path == null) { - HtmlBody += string.Format("

{0}

", "视频不存在"); + HtmlBody += string.Format("

{0}

", "语音不存在"); continue; } HtmlBody += string.Format("

", path); @@ -88,8 +101,8 @@ public void SetMsg(WXReader reader, WXSession session) HtmlBody += string.Format("

{0}

", "暂未支持的消息"); } } - } + } private static DateTime TimeStampToDateTime(long timeStamp, bool inMilli = false) { DateTimeOffset dateTimeOffset = inMilli ? DateTimeOffset.FromUnixTimeMilliseconds(timeStamp) : DateTimeOffset.FromUnixTimeSeconds(timeStamp); diff --git a/Interface/ExportInterface.cs b/Interface/ExportInterface.cs index 95e61b2..e7b2ce0 100644 --- a/Interface/ExportInterface.cs +++ b/Interface/ExportInterface.cs @@ -10,7 +10,8 @@ namespace WechatPCMsgBakTool.Interface public interface IExport { void InitTemplate(WXSession session); - void SetMsg(WXReader reader, WXSession session); + void InitTemplate(WXContact session); + void SetMsg(WXUserReader reader, WXContact session); void SetEnd(); void Save(string path = "", bool append = false); diff --git a/Main.xaml b/Main.xaml new file mode 100644 index 0000000..ca57227 --- /dev/null +++ b/Main.xaml @@ -0,0 +1,38 @@ + + + + + + + + + + +