Selaa lähdekoodia

v0.9.7.3 Release!
1.新增导出时间范围选择

Suxue 1 vuosi sitten
vanhempi
säilyke
5637af45f3

+ 25 - 0
Dialog/MsgDatetimePicker.xaml

@@ -0,0 +1,25 @@
+<Window x:Class="WechatBakTool.Dialog.MsgDatetimePicker"
+        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:WechatBakTool.Dialog"
+        xmlns:local2="clr-namespace:WechatBakTool.ViewModel"
+        WindowStartupLocation="CenterScreen"
+        mc:Ignorable="d"
+        Title="选择导出日期" Height="350" Width="330">
+    <Window.Resources>
+        <local2:DateTypeConverter x:Key="dateTypeConverter" />
+    </Window.Resources>
+    <Grid>
+        <RadioButton GroupName="Date" Content="全部" HorizontalAlignment="Left" Margin="45,60,0,0" VerticalAlignment="Top" IsChecked="{Binding DateType, Converter={StaticResource ResourceKey=dateTypeConverter}, ConverterParameter=1}"/>
+        <RadioButton GroupName="Date" Content="昨天" HorizontalAlignment="Left" Margin="45,90,0,0" VerticalAlignment="Top" IsChecked="{Binding DateType, Converter={StaticResource ResourceKey=dateTypeConverter}, ConverterParameter=2}"/>
+        <RadioButton GroupName="Date" Content="指定日期" HorizontalAlignment="Left" Margin="45,120,0,0" VerticalAlignment="Top" IsChecked="{Binding DateType, Converter={StaticResource ResourceKey=dateTypeConverter}, ConverterParameter=3}"/>
+        <DatePicker  HorizontalAlignment="Left" Margin="45,140,0,0" VerticalAlignment="Top" SelectedDate="{Binding PickDate}"/>
+        <RadioButton GroupName="Date" Content="指定范围日期" HorizontalAlignment="Left" Margin="45,180,0,0" VerticalAlignment="Top" IsChecked="{Binding DateType, Converter={StaticResource ResourceKey=dateTypeConverter}, ConverterParameter=4}"/>
+        <DatePicker Margin="45,200,0,0" VerticalAlignment="Top" SelectedDate="{Binding StartDate}" HorizontalAlignment="Left" Width="100"/>
+        <DatePicker Margin="185,200,0,0" VerticalAlignment="Top" SelectedDate="{Binding EndDate}" HorizontalAlignment="Left" Width="100"/>
+        <Label Content="至" Margin="0,200,0,0" VerticalAlignment="Top" HorizontalAlignment="Center" Width="22"/>
+        <Button Content="提交" Margin="100,265,0,0" VerticalAlignment="Top" Height="40" Click="Button_Click" HorizontalAlignment="Left" Width="140"/>
+    </Grid>
+</Window>

+ 36 - 0
Dialog/MsgDatetimePicker.xaml.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+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 System.Windows.Shapes;
+using WechatBakTool.ViewModel;
+
+namespace WechatBakTool.Dialog
+{
+    /// <summary>
+    /// MsgDatetimePicker.xaml 的交互逻辑
+    /// </summary>
+    public partial class MsgDatetimePicker : Window
+    {
+
+        public MsgDatetimePicker(DatetimePickerViewModel viewModel)
+        {
+            DataContext = viewModel;
+            InitializeComponent();
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+            DialogResult = true;
+            Close();
+        }
+    }
+}

+ 1 - 1
Export/ExportInterface.cs

@@ -11,7 +11,7 @@ namespace WechatBakTool.Export
     public interface IExport
     {
         void InitTemplate(WXContact session,string path);
-        bool SetMsg(WXUserReader reader, WXContact session, WorkspaceViewModel viewModel);
+        bool SetMsg(WXUserReader reader, WXContact session, WorkspaceViewModel viewModel, DatetimePickerViewModel dateModel);
         void SetEnd();
         void Save(string path = "");
     }

+ 2 - 2
Export/HtmlExport.cs

@@ -50,12 +50,12 @@ namespace WechatBakTool.Export
             File.AppendAllText(Path, HtmlBody);
         }
 
-        public bool SetMsg(WXUserReader reader, WXContact contact,WorkspaceViewModel viewModel)
+        public bool SetMsg(WXUserReader reader, WXContact contact,WorkspaceViewModel viewModel, DatetimePickerViewModel dateModel)
         {
             if (Session == null)
                 throw new Exception("请初始化模版:Not Use InitTemplate");
 
-            List<WXMsg>? msgList = reader.GetWXMsgs(contact.UserName);
+            List<WXMsg>? msgList = reader.GetWXMsgs(contact.UserName, dateModel);
             if (msgList == null)
                 throw new Exception("获取消息失败,请确认数据库读取正常");
 

+ 2 - 2
Export/TXTExport.cs

@@ -40,12 +40,12 @@ namespace WechatBakTool.Export
             
         }
 
-        public bool SetMsg(WXUserReader reader, WXContact session, WorkspaceViewModel viewModel)
+        public bool SetMsg(WXUserReader reader, WXContact session, WorkspaceViewModel viewModel, DatetimePickerViewModel dateModel)
         {
             if (Contact == null)
                 throw new Exception("请初始化模版:Not Use InitTemplate");
 
-            List<WXMsg>? msgList = reader.GetWXMsgs(Contact.UserName);
+            List<WXMsg>? msgList = reader.GetWXMsgs(Contact.UserName, dateModel);
             if (msgList == null)
                 throw new Exception("获取消息失败,请确认数据库读取正常");
 

+ 2 - 1
Main2.xaml.cs

@@ -80,6 +80,8 @@ namespace WechatBakTool
                 MainFrame.Navigate(new Uri("pack://application:,,,/Pages/Welcome.xaml?datatime=" + DateTime.Now.Ticks));
                 return;
             }
+
+            CurrentUserBakConfig = config;
             if (!config.Decrypt)
             {
                 MessageBox.Show("请先到创建工作区进行解密");
@@ -87,7 +89,6 @@ namespace WechatBakTool
                 return;
             }
 
-            CurrentUserBakConfig = config;
             MainFrame.Navigate(new Uri("pack://application:,,,/Pages/Workspace.xaml?datatime=" + DateTime.Now.Ticks));
         }
 

+ 2 - 0
Model/WXModel.cs

@@ -25,6 +25,8 @@ namespace WechatBakTool.Model
         public string Account { get; set; } = "";
         public string Friends_Number { get; set; } = "-";
         public string Msg_Number { get; set; } = "-";
+        public string Key { get; set; } = "";
+        public bool Manual { get; set; } = false;
     }
 
     public class WXCount

+ 52 - 6
Pages/CreateWork.xaml.cs

@@ -1,4 +1,5 @@
-using System;
+using JiebaNet.Segmenter.Common;
+using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
@@ -13,7 +14,6 @@ using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
-using System.Windows.Shapes;
 using WechatBakTool.Helpers;
 using WechatBakTool.Model;
 using WechatBakTool.ViewModel;
@@ -29,9 +29,20 @@ namespace WechatBakTool.Pages
         public CreateWork()
         {
             DataContext = ViewModel;
+            
             InitializeComponent();
             GetWechatProcessInfos();
+            isManualProcess();
         }
+        
+        private void isManualProcess()
+        {
+            if(Main2.CurrentUserBakConfig!= null)
+            {
+                cb_manual.IsChecked = Main2.CurrentUserBakConfig.Manual;
+            }
+        }
+        
 
         private void GetWechatProcessInfos()
         {
@@ -97,9 +108,9 @@ namespace WechatBakTool.Pages
         private void btn_create_worksapce_Click(object sender, RoutedEventArgs e)
         {
             ViewModel.IsEnable = false;
-
+            bool m = (bool)cb_manual.IsChecked!;
             Task.Run(() => {
-                if (ViewModel.KeyType != -1)
+                if (ViewModel.KeyType != -1 && !m)
                 {
                     if (ViewModel.SelectProcess != null)
                     {
@@ -141,6 +152,17 @@ namespace WechatBakTool.Pages
                         }
                     }
                 }
+                else if (m)
+                {
+                    WXWorkspace wXWorkspace = new WXWorkspace(Main2.CurrentUserBakConfig!);
+                    ViewModel.LabelStatus = "开始解密数据库";
+                    wXWorkspace.DecryptDB("", -1, ViewModel,Main2.CurrentUserBakConfig!.Key);
+                    Dispatcher.Invoke(() =>
+                    {
+                        MessageBox.Show("解密完成");
+                        ((Main2)Window.GetWindow(this)).LoadWorkspace();
+                    });
+                }
                 else
                 {
                     MessageBox.Show("请选择Key获取方式", "错误");
@@ -152,16 +174,40 @@ namespace WechatBakTool.Pages
         private void cb_manual_Checked(object sender, RoutedEventArgs e)
         {
             MessageBox.Show("该功能仅限用于网络安全研究用途使用,红队同学请在合规授权下进行相关操作","重要提醒!!!!!!!!!");
+            if(Main2.CurrentUserBakConfig != null)
+            {
+                if (Main2.CurrentUserBakConfig.Manual)
+                {
+                    return;
+                }
+            }
             if (MessageBox.Show("我确认获取到合规授权,仅用于网络安全用途使用", "信息确认", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
             {
                 if (File.Exists("auth.txt"))
                 {
                     string auth = File.ReadAllText("auth.txt");
-                    // 我已知晓手动模式可能潜在的法律及道德风险,我明白非法使用将要承担相关法律责任。
+                    /* 
+                     * 
+                     * pwd: 
+                     * 我已知晓手动模式可能潜在的法律及道德风险,我明白非法使用将要承担相关法律责任。
+                     * tips:
+                     * 请不要公开宣传手动模式,不提供任何使用解答,谢谢。
+                     * 不要编写任何关于手动模式的教程,避免非法传播使用。
+                     * 
+                     */
                     if (DecryptionHelper.GetMD5(auth) == "295f634af60d61dfa52a5f35849ac42b")
                     {
+                        string genHash = DateTime.Now.ToString();
+                        string md5 = DecryptionHelper.GetMD5(genHash);
+                        UserBakConfig config = new UserBakConfig();
+                        config.Hash = md5;
+                        string workspacePath = Path.Combine(Directory.GetCurrentDirectory(), "workspace");
+                        config.UserWorkspacePath = Path.Combine(workspacePath, md5);
+
+                        WXWorkspace workspace = new WXWorkspace(config);
+                        workspace.ManualInit();
+
                         MessageBox.Show("已经创建空的配置文件,请完善该配置文件后,点击开始解密","提示");
-                        MessageBox.Show("该功能现阶段暂未启用","错误");
                     }
                 }
                 else

+ 3 - 1
Pages/Manager.xaml.cs

@@ -137,7 +137,9 @@ namespace WechatBakTool.Pages
 
             IExport export = new HtmlExport();
             export.InitTemplate(contact, path);
-            if(export.SetMsg(UserReader!, contact, workspaceViewModel))
+            DatetimePickerViewModel dt = new DatetimePickerViewModel();
+            dt.DateType = 1;
+            if (export.SetMsg(UserReader!, contact, workspaceViewModel, dt))
             {
                 export.SetEnd();
                 export.Save(path);

+ 16 - 25
Pages/Workspace.xaml.cs

@@ -29,6 +29,7 @@ using Newtonsoft.Json;
 using System.Drawing.Imaging;
 using System.Threading;
 using System.Runtime.CompilerServices;
+using WechatBakTool.Dialog;
 
 namespace WechatBakTool.Pages
 {
@@ -158,29 +159,6 @@ namespace WechatBakTool.Pages
             Debug.WriteLine(ViewModel.SearchString);
         }
 
-        private void btn_export_Click(object sender, RoutedEventArgs e)
-        {
-            if(ViewModel.WXContact == null || UserReader == null)
-            {
-                MessageBox.Show("请选择联系人", "错误");
-                return;
-            }
-            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)
-            {
-                MessageBox.Show(ex.Message);
-            }
-            
-            MessageBox.Show("导出完成");
-        }
 
         private void btn_open_workspace_Click(object sender, RoutedEventArgs e)
         {
@@ -201,7 +179,20 @@ namespace WechatBakTool.Pages
                     MessageBox.Show("请选择导出方式", "错误");
                     return;
                 }
-                if(ViewModel.SelectExportItem.Value == 3)
+
+                DatetimePickerViewModel datePickViewModel = new DatetimePickerViewModel();
+                Dispatcher.Invoke(() =>
+                {
+                    MsgDatetimePicker picker = new MsgDatetimePicker(datePickViewModel);
+                    datePickViewModel.DateType = 1;
+                    datePickViewModel.PickDate = DateTime.Now.AddDays(-1);
+                    if (picker.ShowDialog() != true)
+                    {
+                        return;
+                    }
+                });
+
+                if (ViewModel.SelectExportItem.Value == 3)
                 {
                     if(UserReader != null && ViewModel.WXContact != null)
                     {
@@ -307,7 +298,7 @@ namespace WechatBakTool.Pages
                     export = new HtmlExport();
                 }
                 export.InitTemplate(ViewModel.WXContact, path);
-                export.SetMsg(UserReader, ViewModel.WXContact, ViewModel);
+                export.SetMsg(UserReader, ViewModel.WXContact, ViewModel, datePickViewModel);
                 export.SetEnd();
                 export.Save(path);
 #if DEBUG

+ 6 - 0
README.md

@@ -60,6 +60,12 @@ A:工作区->右键->管理,就见了。<br/>
 Q:解密工作区提示no such teble:MSG怎么办<br/>
 A:基本上都是因为刚迁移完,缓存没写入到数据库导致的,建议迁移完重启一次微信后再创建工作区<br/>
 <br/>
+Q:解密工作区提示no such teble:XXXXXXX怎么办<br/>
+A:这个原因基本上是因为解密失败导致的,回落使用固定地址查找方式解密,请确保你的微信版本在version.json内支持<br/>
+<br/>
+Q:解密时提示,Unable to load DLL 'libcrypto-1_1' or one of its dependencies怎么办<br/>
+A:这个是因为加解密库的运行环境不满足,安装vc++2015 x64运行库后再尝试<br/>
+<br/>
 
 ### 使用说明
 0.安装.NET Desktop Runtime(注意是6.0版本的Desktop Runtime,如已经安装忽略)<br/>

+ 39 - 0
ViewModel/DatetimePickerViewModel.cs

@@ -0,0 +1,39 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using WechatBakTool.Model;
+
+namespace WechatBakTool.ViewModel
+{
+    public partial class DatetimePickerViewModel : ObservableObject
+    {
+        [ObservableProperty]
+        private DateTime startDate = DateTime.Now.AddMonths(-1);
+
+        [ObservableProperty]
+        private DateTime endDate = DateTime.Now;
+
+        [ObservableProperty]
+        private DateTime pickDate = DateTime.Now.AddDays(-1);
+
+        [ObservableProperty]
+        private int dateType = 1;
+    }
+
+    public class DateTypeConverter : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            return (int.Parse(parameter.ToString()!) == (int)value);
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            return (bool)value ? parameter : Binding.DoNothing;
+        }
+    }
+}

+ 35 - 0
WXUserReader.cs

@@ -22,6 +22,7 @@ using System.Net.Http;
 using System.Reflection.Metadata;
 using System.Threading;
 using Newtonsoft.Json;
+using WechatBakTool.ViewModel;
 
 namespace WechatBakTool
 {
@@ -379,6 +380,40 @@ namespace WechatBakTool
             }
             return tmp;
         }
+
+        public List<WXMsg>? GetWXMsgs(string uid, DatetimePickerViewModel dateModel)
+        {
+            List<WXMsg> tmp = new List<WXMsg>();
+            for (int i = 0; i <= 99; i++)
+            {
+                SQLiteConnection? con = getCon("MSG" + i.ToString());
+                if (con == null)
+                    return tmp;
+
+                List<WXMsg>? wXMsgs = null;
+                string query = "";
+
+                if (dateModel.DateType == 2 || dateModel.DateType == 3)
+                {
+                    query = "select * from MSG where StrTalker=? and date(createtime,'unixepoch') = ?";
+                    wXMsgs = con.Query<WXMsg>(query, uid, dateModel.PickDate.ToString("yyyy-MM-dd"));
+                }
+                else if(dateModel.DateType == 4 )
+                {
+                    query = "select * from MSG where StrTalker=? and date(createtime,'unixepoch') >= ? and date(createtime,'unixepoch') <= ?";
+                    wXMsgs = con.Query<WXMsg>(query, uid, dateModel.StartDate.ToString("yyyy-MM-dd"), dateModel.EndDate.ToString("yyyy-MM-dd"));
+                }
+                else
+                {
+                    query = "select * from MSG where StrTalker=?";
+                    wXMsgs = con.Query<WXMsg>(query, uid);
+                }
+                
+                tmp.AddRange(ProcessMsg(wXMsgs, uid));
+            }
+            return tmp;
+        }
+
         private List<WXMsg> ProcessMsg(List<WXMsg> msgs,string uid)
         {
             foreach (WXMsg w in msgs)

+ 25 - 14
WXWorkspace.cs

@@ -104,32 +104,42 @@ namespace WechatBakTool
         {
             return UserBakConfig;
         }
-        public static void SaveConfig(UserBakConfig userBakConfig)
+        public static void SaveConfig(UserBakConfig userBakConfig, bool manual = false)
         {
             if(userBakConfig.UserWorkspacePath != "")
             {
                 DirectoryInfo directoryInfo = new DirectoryInfo(userBakConfig.UserWorkspacePath);
                 if(directoryInfo.Parent != null)
                 {
-                    string json_path = Path.Combine(directoryInfo.Parent.FullName, userBakConfig.UserName + ".json");
+                    string json_path = Path.Combine(directoryInfo.Parent.FullName, userBakConfig.Manual ? userBakConfig.Hash + ".json" : userBakConfig.UserName + ".json");
                     string json = JsonConvert.SerializeObject(userBakConfig);
                     File.WriteAllText(json_path, json);
                 }
             }
         }
-        private string Init(string path,bool manual,string account = "")
+
+        public void ManualInit()
+        {
+            Init("", true, "");
+        }
+        private string Init(string path,bool manual = false,string account = "")
         {
             string curPath = AppDomain.CurrentDomain.BaseDirectory;
-            string md5 = GetMd5Hash(path);
-            string[] paths = path.Split(new string[] { "/", "\\" }, StringSplitOptions.None);
-            string username = paths[paths.Length - 1];
-            UserBakConfig.UserResPath = path;
-            UserBakConfig.UserWorkspacePath = Path.Combine(curPath, "workspace", md5);
-            UserBakConfig.Hash = md5;
-            UserBakConfig.UserName = username;
-            UserBakConfig.Account = account;
-
-            if (!Directory.Exists(UserBakConfig.UserResPath))
+            if (!manual)
+            {
+                string md5 = GetMd5Hash(path);
+                string[] paths = path.Split(new string[] { "/", "\\" }, StringSplitOptions.None);
+                string username = paths[paths.Length - 1];
+                UserBakConfig.UserResPath = path;
+                UserBakConfig.UserWorkspacePath = Path.Combine(curPath, "workspace", md5);
+                UserBakConfig.Hash = md5;
+                UserBakConfig.UserName = username;
+                UserBakConfig.Account = account;
+            }
+
+            UserBakConfig.Manual = manual;
+
+            if (!Directory.Exists(UserBakConfig.UserResPath) && !manual)
             {
                 return "用户资源文件夹不存在,如需使用离线数据,请从工作区读取";
             }
@@ -141,6 +151,7 @@ namespace WechatBakTool
 
             string db = Path.Combine(UserBakConfig.UserWorkspacePath, "OriginalDB");
             string decDb = Path.Combine(UserBakConfig.UserWorkspacePath, "DecDB");
+
             if (!Directory.Exists(db))
             {
                 Directory.CreateDirectory (db);
@@ -149,7 +160,7 @@ namespace WechatBakTool
             {
                 Directory.CreateDirectory(decDb);
             }
-            SaveConfig(UserBakConfig);
+            SaveConfig(UserBakConfig, manual);
             return "";
         }
 

+ 3 - 3
WechatBakTool.csproj

@@ -6,9 +6,9 @@
     <Nullable>enable</Nullable>
     <UseWPF>true</UseWPF>
     <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
-    <AssemblyVersion>0.9.7.2</AssemblyVersion>
-    <FileVersion>0.9.7.2</FileVersion>
-    <Version>0.9.7.2</Version>
+    <AssemblyVersion>0.9.7.3</AssemblyVersion>
+    <FileVersion>0.9.7.3</FileVersion>
+    <Version>0.9.7.3</Version>
   </PropertyGroup>
 
   <ItemGroup>