浏览代码

1.修复导出html时,emoji xml导致线程退出的问题
2.修复图片导出问题

Suxue 1 年之前
父节点
当前提交
f02a1164cf
共有 4 个文件被更改,包括 88 次插入96 次删除
  1. 34 82
      Helpers/DecryptionHelper.cs
  2. 10 8
      Helpers/NativeAPIHelper.cs
  3. 15 6
      Pages/Workspace.xaml.cs
  4. 29 0
      WXUserReader.cs

+ 34 - 82
Helpers/DecryptionHelper.cs

@@ -5,6 +5,7 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
+using System.Reflection.PortableExecutable;
 using System.Security.Cryptography;
 using System.Text;
 using System.Text.Json.Serialization;
@@ -179,99 +180,50 @@ namespace WechatBakTool.Helpers
         {
             return BitConverter.ToString(bytes, 0).Replace("-", string.Empty).ToLower().ToUpper();
         }
+
+        private static List<byte[]> ImgHeader = new List<byte[]>()
+        {
+            new byte[] { 0xFF, 0xD8 },//JPG
+            new byte[] { 0x89, 0x50 },//PNG
+            new byte[] { 0x42, 0x4D },//BMP
+            new byte[] { 0x47, 0x49 },//GIF
+            new byte[] { 0x49, 0x49 },//TIF
+            new byte[] { 0x4D, 0x4D },//TIF
+        };
         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++)
+            foreach (byte[] b in ImgHeader)
             {
-                byte[] buf = new byte[8];
-                raw.CopyTo(buf, 0);
-
-                if (CheckFileType(ConvertData(buf, key)) != ".dat")
+                byte t = (byte)(fileBytes[0] ^ b[0]);
+                byte[] decData = fileBytes.Select(b => (byte)(b ^ t)).ToArray();
+                if (b[1] != decData[1])
+                    continue;
+                else
                 {
-                    return key;
+                    return decData;
                 }
             }
-            return 0x00;
+            return new byte[0];
         }
-        private static byte[] ConvertData(byte[] data, byte key)
+        public static string CheckFileType(byte[] data)
         {
-            for (int i = 0; i < data.Length; i++)
-            {
-                data[i] ^= key;
-            }
-
-            return data;
+            if (data[0] == 0xFF && data[1] == 0xD8)
+                return ".jpg";
+            else if (data[0] == 0x89 && data[1] == 0x50)
+                return ".png";
+            else if (data[0] == 0x42 && data[1] == 0X4D)
+                return ".bmp";
+            else if (data[0] == 0x47 && data[1] == 0x49)
+                return ".gif";
+            else if (data[0] == 0x49 && data[1] == 0x49)
+                return ".tif";
+            else if (data[0] == 0x4D && data[1] == 0x4D)
+                return ".tif";
+            else
+                return ".dat";
         }
         public static string SaveDecImage(byte[] fileRaw,string source,string to_dir,string type)
         {

+ 10 - 8
Helpers/NativeAPIHelper.cs

@@ -48,17 +48,19 @@ namespace WechatBakTool.Helpers
                 uint nLength = 0;
                 hObjectName = AllocManagedMemory(256 * 1024);
 
-                // 查询句柄名称
-                while (NtQueryObject(ipHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength) == NTSTATUS_STATUS_INFO_LENGTH_MISMATCH)
+                Task.Run(() =>
                 {
-                    FreeManagedMemory(hObjectName);
-                    if (nLength == 0)
+                    // 查询句柄名称
+                    while (NtQueryObject(ipHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength) == NTSTATUS_STATUS_INFO_LENGTH_MISMATCH)
                     {
-                        Console.WriteLine("Length returned at zero!");
-                        return "";
+                        FreeManagedMemory(hObjectName);
+                        if (nLength == 0)
+                        {
+                            Console.WriteLine("Length returned at zero!");
+                        }
+                        hObjectName = AllocManagedMemory(nLength);
                     }
-                    hObjectName = AllocManagedMemory(nLength);
-                }
+                }).Wait(100);
                 OBJECT_NAME_INFORMATION? objObjectName = new OBJECT_NAME_INFORMATION();
                 objObjectName = Marshal.PtrToStructure(hObjectName, objObjectName.GetType()) as OBJECT_NAME_INFORMATION?;
                 if (objObjectName == null)

+ 15 - 6
Pages/Workspace.xaml.cs

@@ -17,6 +17,7 @@ using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using WechatBakTool.Export;
+using WechatBakTool.Helpers;
 using WechatBakTool.Model;
 using WechatBakTool.ViewModel;
 
@@ -100,12 +101,20 @@ namespace WechatBakTool.Pages
                 MessageBox.Show("请选择联系人", "错误");
                 return;
             }
-            string path = Path.Combine(Main2.CurrentUserBakConfig!.UserWorkspacePath, ViewModel.WXContact.UserName + ".txt");
-            IExport export = new TXTExport();
-            export.InitTemplate(ViewModel.WXContact, path);
-            export.SetMsg(UserReader, ViewModel.WXContact, ViewModel);
-            export.SetEnd();
-            export.Save(path);
+            try
+            {
+                string path = Path.Combine(Main2.CurrentUserBakConfig!.UserWorkspacePath, ViewModel.WXContact.UserName + ".txt");
+                IExport export = new TXTExport();
+                export.InitTemplate(ViewModel.WXContact, path);
+                export.SetMsg(UserReader, ViewModel.WXContact, ViewModel);
+                export.SetEnd();
+                export.Save(path);
+            }catch(Exception ex)
+            {
+                File.AppendAllText("1.log", ex.Message);
+                MessageBox.Show(ex.Message);
+            }
+            
             MessageBox.Show("导出完成");
         }
 

+ 29 - 0
WXUserReader.cs

@@ -507,6 +507,32 @@ namespace WechatBakTool
                 }
                 path = tmp_file_path;
             }
+            else if (type == WXMsgType.Emoji)
+            {
+                try
+                {
+                    XmlDocument xmlDocument = new XmlDocument();
+                    xmlDocument.LoadXml(msg.StrContent);
+                    XmlNode? node = xmlDocument.SelectSingleNode("/msg/emoji");
+                    if (node != null)
+                    {
+                        if (node.Attributes != null)
+                        {
+                            XmlNode? item = node.Attributes.GetNamedItem("md5");
+                            string md5 = item != null ? item.InnerText : "";
+                            if (EmojiCache.ContainsKey(md5))
+                            {
+                                path = string.Format("Emoji\\{0}.gif", md5);
+                            }
+                        }
+                    }
+                }
+                catch
+                {
+                    return null;
+                }
+                
+            }
 
             if (path == null)
                 return null;
@@ -565,6 +591,8 @@ namespace WechatBakTool
                     // 图片的路径是相对路径,需要加上资源目录
                     path = Path.Combine(UserBakConfig.UserResPath, path);
                     byte[] decFileByte = DecryptionHelper.DecImage(path);
+                    if (decFileByte.Length < 2)
+                        new Exception("解密失败,可能是未支持的格式");
                     string decFiletype = DecryptionHelper.CheckFileType(decFileByte);
                     file_path = DecryptionHelper.SaveDecImage(decFileByte, path, img_dir, decFiletype);
                     break;
@@ -611,5 +639,6 @@ namespace WechatBakTool
         Video = 1,
         Audio = 2,
         File = 3,
+        Emoji = 4,
     }
 }