Jelajahi Sumber

新增用户名推定key地址,请确保新建工作区时填写当前账号
现在用户搜索支持了昵称、备注模糊搜索
增加了3.9.8.15 key地址

Suxue 1 tahun lalu
induk
melakukan
31c28d8111
13 mengubah file dengan 335 tambahan dan 42 penghapusan
  1. 47 21
      Helpers/DecryptionHelper.cs
  2. 39 9
      Helpers/ProcessHelper.cs
  3. 4 2
      Main.xaml
  4. 20 2
      Main.xaml.cs
  5. 1 0
      Model/Common.cs
  6. 1 0
      Model/WXModel.cs
  7. 6 3
      SelectWechat.xaml
  8. 11 0
      SelectWechat.xaml.cs
  9. 15 0
      Tools.xaml
  10. 167 0
      Tools.xaml.cs
  11. 17 2
      WXUserReader.cs
  12. 4 3
      WXWorkspace.cs
  13. 3 0
      version.json

+ 47 - 21
Helpers/DecryptionHelper.cs

@@ -9,6 +9,7 @@ using System.Security.Cryptography;
 using System.Text;
 using System.Text.Json.Serialization;
 using System.Threading.Tasks;
+using System.Windows;
 using WechatPCMsgBakTool.Model;
 
 namespace WechatPCMsgBakTool.Helpers
@@ -22,7 +23,7 @@ namespace WechatPCMsgBakTool.Helpers
         const int DEFAULT_ITER = 64000;
         const int DEFAULT_PAGESIZE = 4096; //4048数据 + 16IV + 20 HMAC + 12
         const string SQLITE_HEADER = "SQLite format 3";
-        public static byte[]? GetWechatKey()
+        public static byte[]? GetWechatKey(bool mem_find_key,string account)
         {
             Process? process = ProcessHelper.GetProcess("WeChat");
             if (process == null)
@@ -40,31 +41,56 @@ namespace WechatPCMsgBakTool.Helpers
                 return null;
             }
 
-            List<VersionInfo>? info = null;
-
-            string json = File.ReadAllText("version.json");
-            info = JsonConvert.DeserializeObject<List<VersionInfo>?>(json);
             
-            if (info == null)
-                return null;
-            if (info.Count == 0)
-                return null;
 
-            VersionInfo? cur = info.Find(x => x.Version == version);
-            if (cur == null)
-                return null;
+            if (!mem_find_key)
+            {
+                List<VersionInfo>? info = null;
+                string json = File.ReadAllText("version.json");
+                info = JsonConvert.DeserializeObject<List<VersionInfo>?>(json);
+                if (info == null)
+                    return null;
+                if (info.Count == 0)
+                    return null;
 
-            //这里加的是版本偏移量,兼容不同版本把这个加给改了
-            long baseAddress = (long)module.BaseAddress + cur.BaseAddr;
-            byte[]? bytes = ProcessHelper.ReadMemoryDate(process.Handle, (IntPtr)baseAddress, 8);
-            if (bytes != null)
+                VersionInfo? cur = info.Find(x => x.Version == version);
+                if (cur == null)
+                    return null;
+                //这里加的是版本偏移量,兼容不同版本把这个加给改了
+                long baseAddress = (long)module.BaseAddress + cur.BaseAddr;
+                byte[]? bytes = ProcessHelper.ReadMemoryDate(process.Handle, (IntPtr)baseAddress, 8);
+                if (bytes != null)
+                {
+                    IntPtr baseAddress2 = (IntPtr)(((long)bytes[7] << 56) + ((long)bytes[6] << 48) + ((long)bytes[5] << 40) + ((long)bytes[4] << 32) + ((long)bytes[3] << 24) + ((long)bytes[2] << 16) + ((long)bytes[1] << 8) + (long)bytes[0]);
+                    byte[]? twoGet = ProcessHelper.ReadMemoryDate(process.Handle, baseAddress2, 32);
+                    if (twoGet != null)
+                    {
+                        string key = BytesToHex(twoGet);
+                        return twoGet;
+                    }
+                }
+            }
+            else
             {
-                IntPtr baseAddress2 = (IntPtr)(((long)bytes[7] << 56) + ((long)bytes[6] << 48) + ((long)bytes[5] << 40) + ((long)bytes[4] << 32) + ((long)bytes[3] << 24) + ((long)bytes[2] << 16) + ((long)bytes[1] << 8) + (long)bytes[0]);
-                byte[]? twoGet = ProcessHelper.ReadMemoryDate(process.Handle, baseAddress2, 32);
-                if (twoGet != null)
+                List<int> read = ProcessHelper.FindProcessMemory(process.Handle, module, account);
+                if(read.Count >= 2)
+                {
+                    byte[] buffer = new byte[8];
+                    int key_offset = read[1] - 64;
+                    if (ProcessHelper.ReadProcessMemory(process.Handle, module.BaseAddress + key_offset, buffer, buffer.Length, out _))
+                    {
+                        ulong addr = BitConverter.ToUInt64(buffer, 0);
+
+                        byte[] key_bytes = new byte[32];
+                        if(ProcessHelper.ReadProcessMemory(process.Handle, (IntPtr)addr, key_bytes, key_bytes.Length, out _))
+                        {
+                            return key_bytes;
+                        }
+                    }
+                }
+                else
                 {
-                    string key = BytesToHex(twoGet);
-                    return twoGet;
+                    MessageBox.Show("搜索不到微信账号,请确认用户名是否正确,如错误请重新新建工作区,务必确认账号是否正确", "错误");
                 }
             }
             return null;

+ 39 - 9
Helpers/ProcessHelper.cs

@@ -13,11 +13,9 @@ namespace WechatPCMsgBakTool.Helpers
     public class ProcessHelper
     {
         private const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
-        private const int DUPLICATE_CLOSE_SOURCE = 0x1;
         private const int DUPLICATE_SAME_ACCESS = 0x2;
 
         private const int CNST_SYSTEM_HANDLE_INFORMATION = 0x10;
-        private const int OBJECT_TYPE_MUTANT = 17;
 
         public static Process GetProcess(string ProcessName)
         {
@@ -50,6 +48,41 @@ namespace WechatPCMsgBakTool.Helpers
             return null;
         }
 
+        public static List<int> FindProcessMemory(IntPtr processHandle, ProcessModule module, string content)
+        {
+            byte[] buffer = new byte[module.ModuleMemorySize];
+            byte[] search = Encoding.ASCII.GetBytes(content);
+            // 逐页读取数据
+
+            List<int> offset = new List<int>();
+            int readBytes;
+            bool success = ReadProcessMemory(processHandle, module.BaseAddress, buffer, buffer.Length,out readBytes);
+
+            if (!success || readBytes == 0)
+            {
+                int error = Marshal.GetLastWin32Error();
+                Console.WriteLine($"ReadProcessMemory failed. GetLastError: {error}");
+            }
+            else
+            {
+                for (int i = 0; i < buffer.Length; i++)
+                {
+                    if (buffer[i] == search[0])
+                    {
+                        for (int s = 1; s < search.Length; s++)
+                        {
+                            if (buffer[i + s] != search[s])
+                                break;
+                            if (s == search.Length - 1)
+                                offset.Add(i);
+                        }
+
+                    }
+                }
+            }
+            return offset;
+        }
+
         public static List<SYSTEM_HANDLE_INFORMATION> GetHandles(Process process)
         {
             List<SYSTEM_HANDLE_INFORMATION> aHandles = new List<SYSTEM_HANDLE_INFORMATION>();
@@ -147,14 +180,15 @@ namespace WechatPCMsgBakTool.Helpers
         public static byte[]? ReadMemoryDate(IntPtr hProcess, IntPtr lpBaseAddress, int nSize = 100)
         {
             byte[] array = new byte[nSize];
-            if (ReadProcessMemory(hProcess, lpBaseAddress, array, nSize, 0) == 0)
+            int readByte;
+            if (ReadProcessMemory(hProcess, lpBaseAddress, array, nSize, out readByte))
                 return null;
             else
                 return array;
         }
 
-        [DllImport("kernel32.dll")]
-        public static extern int ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, int lpNumberOfBytesRead);
+        [DllImport("kernel32.dll", SetLastError = true)]
+        public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int nSize, out int lpNumberOfBytesRead);
         [DllImport("ntdll.dll")]
         private static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
 
@@ -174,10 +208,6 @@ namespace WechatPCMsgBakTool.Helpers
         [DllImport("kernel32.dll")]
         private static extern bool CloseHandle(IntPtr hObject);
 
-        [DllImport("kernel32.dll")]
-        private static extern bool GetHandleInformation(IntPtr hObject, out uint lpdwFlags);
-
-
         [StructLayout(LayoutKind.Sequential, Pack = 1)]
         public struct SYSTEM_HANDLE_INFORMATION
         { // Information Class 16

+ 4 - 2
Main.xaml

@@ -18,9 +18,9 @@
         </ListView>
         <Label Content="工作区:" HorizontalAlignment="Left" Margin="15,15,0,0" VerticalAlignment="Top" Height="25" Width="58"/>
         <Button Content="新增" Width="50" HorizontalAlignment="Left" Margin="194,20,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.343,0.521" Height="19" Click="Button_Click_1"/>
-        <Label Content="用户路径:-" Name="user_path" HorizontalAlignment="Left" Margin="278,50,0,0" VerticalAlignment="Top" Height="25" Width="500"/>
+        <Label Content="用户路径:-" Name="user_path" HorizontalAlignment="Left" Margin="278,68,0,0" VerticalAlignment="Top" Height="25" Width="500"/>
         <Button Content="解密" IsEnabled="False" Width="50" HorizontalAlignment="Left" Margin="285,20,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.343,0.521" Name="btn_decrypt" Click="btn_decrypt_Click" Height="19"/>
-        <Button Content="读取" IsEnabled="False" Width="50" HorizontalAlignment="Left" Margin="365,20,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.343,0.521" Name="btn_read" Click="btn_read_Click" Height="19" />
+        <Button Content="读取" IsEnabled="False" Width="50" HorizontalAlignment="Left" Margin="285,47,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.343,0.521" Name="btn_read" Click="btn_read_Click" Height="19" />
 
         <ListView Name="list_sessions" Margin="278,130,0,20" HorizontalAlignment="Left" Width="290" MouseDoubleClick="list_sessions_MouseDoubleClick">
             <ListView.View>
@@ -36,5 +36,7 @@
         <Button Name="btn_search" Content="搜索" HorizontalAlignment="Left" Margin="525,96,0,0" VerticalAlignment="Top" Width="43" Click="btn_search_Click"/>
         <Button Name="btn_analyse" Content="消息分析工具" HorizontalAlignment="Left" Margin="609,160,0,0" VerticalAlignment="Top" Width="140" Click="btn_analyse_Click"/>
         <CheckBox Name="cb_del_search" Content="已删除人员强制从记录搜索" HorizontalAlignment="Left" Margin="610,99,0,0" VerticalAlignment="Top"/>
+        <RadioButton Name="rb_find_file" GroupName="find_addr_function" Content="使用version.json进行基址查找" HorizontalAlignment="Left" Margin="348,22,0,0" VerticalAlignment="Top" IsChecked="True"/>
+        <RadioButton Name="rb_find_mem" GroupName="find_addr_function" Content="使用推定进行基址查找【推荐】" HorizontalAlignment="Left" Margin="546,22,0,0" VerticalAlignment="Top" Checked="rb_find_mem_Checked"/>
     </Grid>
 </Window>

+ 20 - 2
Main.xaml.cs

@@ -86,10 +86,16 @@ namespace WechatPCMsgBakTool
             {
                 if (!CurrentUserBakConfig.Decrypt)
                 {
+                    bool? mem_find_key = rb_find_mem.IsChecked;
+                    if(mem_find_key == null)
+                    {
+                        MessageBox.Show("请选择key获取方式");
+                        return;
+                    }
                     byte[]? key = null;
                     try
                     {
-                         key = DecryptionHelper.GetWechatKey();
+                         key = DecryptionHelper.GetWechatKey((bool)mem_find_key,CurrentUserBakConfig.Account);
                     }
                     catch (Exception ex)
                     {
@@ -196,7 +202,7 @@ namespace WechatPCMsgBakTool
                 string path = selectWechat.SelectProcess.DBPath.Replace("\\Msg\\MicroMsg.db", "");
                 try
                 {
-                    WXWorkspace wXWorkspace = new WXWorkspace(path);
+                    WXWorkspace wXWorkspace = new WXWorkspace(path, selectWechat.SelectProcess.Account);
                     wXWorkspace.MoveDB();
                     MessageBox.Show("创建工作区成功");
                     LoadWorkspace();
@@ -246,5 +252,17 @@ namespace WechatPCMsgBakTool
             Analyse analyse = new Analyse(CurrentUserBakConfig, UserReader);
             analyse.Show();
         }
+
+        private void rb_find_mem_Checked(object sender, RoutedEventArgs e)
+        {
+            if(CurrentUserBakConfig!= null)
+            {
+                if (string.IsNullOrEmpty(CurrentUserBakConfig.Account))
+                {
+                    MessageBox.Show("使用该功能需要填写用户名,请务必确认用户名已经正确填写,否则请重建工作区");
+                    return;
+                }
+            }
+        }
     }
 }

+ 1 - 0
Model/Common.cs

@@ -11,6 +11,7 @@ namespace WechatPCMsgBakTool.Model
         public string ProcessName { get; set; } = "";
         public string ProcessId { get; set; } = "";
         public string DBPath { get; set; } = "";
+        public string Account { get; set; } = "";
     }
     public class DBInfo
     {

+ 1 - 0
Model/WXModel.cs

@@ -16,6 +16,7 @@ namespace WechatPCMsgBakTool.Model
         public string Hash { get; set; } = "";
         public string NickName { get; set; } = "";
         public string UserName { get; set; } = "";
+        public string Account { get; set; } = "";
 
         public event PropertyChangedEventHandler? PropertyChanged;
         private void OnPropertyChanged(string propertyName)

+ 6 - 3
SelectWechat.xaml

@@ -6,10 +6,10 @@
         xmlns:local="clr-namespace:WechatPCMsgBakTool"
         mc:Ignorable="d"
         WindowStartupLocation="CenterScreen"
-        Title="选择微信" Height="300" Width="600">
+        Title="选择微信" Height="310" Width="600">
     <Grid>
         <Label Content="请选择您要打开的微信:" HorizontalAlignment="Left" Margin="29,27,0,0" VerticalAlignment="Top"/>
-        <ListView Name="list_process" Margin="32,55,32,67" SelectionChanged="list_process_SelectionChanged">
+        <ListView Name="list_process" Margin="32,55,32,110" SelectionChanged="list_process_SelectionChanged" >
             <ListView.View>
                 <GridView>
                     <GridViewColumn Header="进程名" Width="80" DisplayMemberBinding="{Binding ProcessName}" />
@@ -18,7 +18,10 @@
                 </GridView>
             </ListView.View>
         </ListView>
-        <Button Name="btn_close" Content="确定并返回" HorizontalAlignment="Left" Margin="240,231,0,0" VerticalAlignment="Top" Width="97" Click="btn_close_Click"/>
+        <Button Name="btn_close" Content="确定并返回" HorizontalAlignment="Left" Margin="241,245,0,0" VerticalAlignment="Top" Width="97" Click="btn_close_Click"/>
+        <Label Content="用户名:" HorizontalAlignment="Left" Margin="34,190,0,0" VerticalAlignment="Top"/>
+        <TextBox Name="txt_username" HorizontalAlignment="Left" Margin="95,195,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="297"/>
+        <Label Content="注意确认用户名是否正确,如修改过用户名,请自行填写!如果需要使用推定方式获取Key必须正确!" HorizontalAlignment="Left" Margin="35,215,0,0" VerticalAlignment="Top" FontWeight="Bold"/>
 
     </Grid>
 </Window>

+ 11 - 0
SelectWechat.xaml.cs

@@ -122,10 +122,21 @@ namespace WechatPCMsgBakTool
         private void list_process_SelectionChanged(object sender, SelectionChangedEventArgs e)
         {
             SelectProcess = list_process.SelectedItem as ProcessInfo;
+            if(SelectProcess != null)
+            {
+                string[] name_raw = SelectProcess.DBPath.Split("\\");
+                txt_username.Text = name_raw[name_raw.Length - 3];
+                
+            }
+            
         }
 
         private void btn_close_Click(object sender, RoutedEventArgs e)
         {
+            if (SelectProcess != null)
+            {
+                SelectProcess.Account = txt_username.Text;
+            }
             Close();
         }
     }

+ 15 - 0
Tools.xaml

@@ -0,0 +1,15 @@
+<Window x:Class="WechatPCMsgBakTool.Tools"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:WechatPCMsgBakTool"
+        mc:Ignorable="d"
+        Title="资源回退工具" Height="450" Width="800" WindowStartupLocation="CenterScreen">
+    <Grid>
+        <Button Name="back_video_file" Content="回退视频文件" HorizontalAlignment="Left" Margin="191,39,0,0" VerticalAlignment="Top" Height="28" Width="96" Click="back_video_file_Click"/>
+        <TextBox Name="txt_log" VerticalScrollBarVisibility="Auto" Margin="40,88,40,31" TextWrapping="Wrap" Text="" AcceptsReturn="True" IsReadOnly="True"/>
+        <ComboBox Name="list_workspace" DisplayMemberPath="UserName" HorizontalAlignment="Left" Margin="40,43,0,0" VerticalAlignment="Top" Width="120"/>
+
+    </Grid>
+</Window>

+ 167 - 0
Tools.xaml.cs

@@ -0,0 +1,167 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using WechatPCMsgBakTool.Model;
+
+namespace WechatPCMsgBakTool
+{
+    /// <summary>
+    /// Tools.xaml 的交互逻辑
+    /// </summary>
+    public partial class Tools : Window
+    {
+        public Tools()
+        {
+            InitializeComponent();
+            LoadWorkspace();
+        }
+
+        private void LoadWorkspace()
+        {
+            list_workspace.Items.Clear();
+            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "workspace");
+            if (Directory.Exists(path))
+            {
+                string[] files = Directory.GetFiles(path);
+                foreach (string file in files)
+                {
+                    string type = file.Substring(file.Length - 5, 5);
+                    if (type == ".json")
+                    {
+                        string jsonString = File.ReadAllText(file);
+                        UserBakConfig? userBakConfig = null;
+                        try
+                        {
+                            userBakConfig = JsonConvert.DeserializeObject<UserBakConfig>(jsonString);
+                        }
+                        catch
+                        {
+                            MessageBox.Show("读取到异常工作区文件,请确认备份数据是否正常\r\n文件路径:" + file, "错误");
+                        }
+                        if (userBakConfig != null)
+                        {
+                            list_workspace.Items.Add(userBakConfig);
+                        }
+                    }
+                }
+            }
+        }
+
+        private void back_video_file_Click(object sender, RoutedEventArgs e)
+        {
+            Task.Run(() => {
+                UserBakConfig? selectConfig = null;
+                Dispatcher.Invoke(() => {
+                    selectConfig = list_workspace.SelectedItem as UserBakConfig;
+                });
+                if (selectConfig != null)
+                {
+                    if (!selectConfig.Decrypt)
+                    {
+                        MessageBox.Show("工作区未解密,请先用主程序进行解密");
+                        return;
+                    }
+
+                    // 检查工作区视频文件夹
+                    string video_dir = Path.Combine(selectConfig.UserWorkspacePath, "Video");
+                    string[] files = Directory.GetFiles(video_dir);
+                    if (!Directory.Exists(video_dir))
+                    {
+                        Dispatcher.Invoke(() => {
+                            txt_log.Text += video_dir + "不存在\r\n";
+                            txt_log.ScrollToEnd();
+                        });
+                        return;
+                    }
+
+                    WXUserReader UserReader = new WXUserReader(selectConfig);
+                    // 获取用户
+                    var atc_list = UserReader.GetWXMsgAtc();
+                    if(atc_list == null)
+                    {
+                        Dispatcher.Invoke(() => {
+                            txt_log.Text += "视频列表没有内容,无法回退\r\n";
+                            txt_log.ScrollToEnd();
+                        });
+                        return;
+                    }
+                    foreach (string file in files)
+                    {
+                        FileInfo fileInfo = new FileInfo(file);
+                        var search = atc_list.FindAll(x => x.attachPath.Contains(fileInfo.Name));
+                        if (search != null)
+                        {
+                            WXSessionAttachInfo? select_atc = null;
+                            if (search.Count > 1)
+                            {
+                                foreach (var s in search)
+                                {
+                                    Dispatcher.Invoke(() =>
+                                    {
+                                        txt_log.Text += s + "\r\n";
+                                        txt_log.ScrollToEnd();
+                                    });
+                                    if (s.attachPath.Contains("_raw"))
+                                        select_atc = s;
+                                }
+                            }
+                            else if (search.Count == 1)
+                                select_atc = search[0];
+                            else
+                            {
+                                Dispatcher.Invoke(() =>
+                                {
+                                    txt_log.Text += "匹配不到文件\r\n";
+                                    txt_log.ScrollToEnd();
+                                });
+                                continue;
+                            }
+
+                            if (select_atc == null)
+                            {
+                                Dispatcher.Invoke(() =>
+                                {
+                                    txt_log.Text += "匹配失败\r\n";
+                                    txt_log.ScrollToEnd();
+                                });
+                                continue;
+                            }
+                                
+                            // 建立路径
+                            string source_video_file = Path.Combine(selectConfig.UserResPath, select_atc.attachPath);
+                            if (File.Exists(source_video_file))
+                            {
+                                Dispatcher.Invoke(() => {
+                                    txt_log.Text += source_video_file + "已经存在\r\n";
+                                    txt_log.ScrollToEnd();
+                                });
+
+                                continue;
+                            }
+                            else
+                            {
+                                Dispatcher.Invoke(() => {
+                                    txt_log.Text += source_video_file + "开始发起回退\r\n";
+                                    txt_log.ScrollToEnd();
+                                });
+                                File.Copy(fileInfo.FullName, source_video_file);
+                            }
+                        }
+                    }
+                }
+            });
+            
+        }
+    }
+}

+ 17 - 2
WXUserReader.cs

@@ -46,8 +46,8 @@ namespace WechatPCMsgBakTool
             string query = "select * from contact";
             if (name != null)
             {
-                query = "select * from contact where username = ? or alias = ?";
-                return con.Query<WXContact>(query, name, name);
+                query = "select * from contact where username like ? or alias like ? or nickname like ? or remark like ?";
+                return con.Query<WXContact>(query, $"%{name}%", $"%{name}%", $"%{name}%", $"%{name}%");
             }
             return con.Query<WXContact>(query);
         }
@@ -88,6 +88,21 @@ namespace WechatPCMsgBakTool
             }
             return tmp;
         }
+        public List<WXSessionAttachInfo>? GetWXMsgAtc()
+        {
+            SQLiteConnection con = DBInfo["MultiSearchChatMsg"];
+            if (con == null)
+                return null;
+
+            string query = "select * from SessionAttachInfo";
+            List<WXSessionAttachInfo> list = con.Query<WXSessionAttachInfo>(query);
+            if (list.Count != 0)
+            {
+                return list;
+            }
+            else
+                return null;
+        }
         public WXSessionAttachInfo? GetWXMsgAtc(WXMsg msg)
         {
             SQLiteConnection con = DBInfo["MultiSearchChatMsg"];

+ 4 - 3
WXWorkspace.cs

@@ -14,8 +14,8 @@ namespace WechatPCMsgBakTool
     public class WXWorkspace
     {
         private UserBakConfig UserBakConfig = new UserBakConfig();
-        public WXWorkspace(string path) {
-            string checkResult = Init(path);
+        public WXWorkspace(string path,string account = "") {
+            string checkResult = Init(path, account);
             if (checkResult != "")
                 new Exception(checkResult);
         }
@@ -64,7 +64,7 @@ namespace WechatPCMsgBakTool
                 }
             }
         }
-        private string Init(string path)
+        private string Init(string path,string account = "")
         {
             string curPath = AppDomain.CurrentDomain.BaseDirectory;
             string md5 = GetMd5Hash(path);
@@ -74,6 +74,7 @@ namespace WechatPCMsgBakTool
             UserBakConfig.UserWorkspacePath = Path.Combine(curPath, "workspace", md5);
             UserBakConfig.Hash = md5;
             UserBakConfig.UserName = username;
+            UserBakConfig.Account = account;
 
             if (!Directory.Exists(UserBakConfig.UserResPath))
             {

+ 3 - 0
version.json

@@ -8,5 +8,8 @@
 	},{
 		"Version":"3.9.7.29",
 		"BaseAddr": 63488256
+	},{
+		"Version":"3.9.8.15",
+		"BaseAddr": 64997904
 	}
 ]