Skip to content

Commit

Permalink
新增用户名推定key地址,请确保新建工作区时填写当前账号
Browse files Browse the repository at this point in the history
现在用户搜索支持了昵称、备注模糊搜索
增加了3.9.8.15 key地址
  • Loading branch information
SuxueCode committed Nov 15, 2023
1 parent e3cfc67 commit 31c28d8
Show file tree
Hide file tree
Showing 13 changed files with 335 additions and 42 deletions.
68 changes: 47 additions & 21 deletions Helpers/DecryptionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows;
using WechatPCMsgBakTool.Model;

namespace WechatPCMsgBakTool.Helpers
Expand All @@ -22,7 +23,7 @@ public class DecryptionHelper
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)
Expand All @@ -40,31 +41,56 @@ public class DecryptionHelper
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;
Expand Down
48 changes: 39 additions & 9 deletions Helpers/ProcessHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -50,6 +48,41 @@ public static Process GetProcess(string ProcessName)
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>();
Expand Down Expand Up @@ -147,14 +180,15 @@ public static string FindHandleName(SYSTEM_HANDLE_INFORMATION systemHandleInform
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);

Expand All @@ -174,10 +208,6 @@ public static string FindHandleName(SYSTEM_HANDLE_INFORMATION systemHandleInform
[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
Expand Down
6 changes: 4 additions & 2 deletions Main.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
22 changes: 20 additions & 2 deletions Main.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,16 @@ private void btn_decrypt_Click(object sender, RoutedEventArgs e)
{
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)
{
Expand Down Expand Up @@ -196,7 +202,7 @@ private void Button_Click_1(object sender, RoutedEventArgs e)
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();
Expand Down Expand Up @@ -246,5 +252,17 @@ private void btn_analyse_Click(object sender, RoutedEventArgs e)
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 change: 1 addition & 0 deletions Model/Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class ProcessInfo
public string ProcessName { get; set; } = "";
public string ProcessId { get; set; } = "";
public string DBPath { get; set; } = "";
public string Account { get; set; } = "";
}
public class DBInfo
{
Expand Down
1 change: 1 addition & 0 deletions Model/WXModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class UserBakConfig : INotifyPropertyChanged
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)
Expand Down
9 changes: 6 additions & 3 deletions SelectWechat.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -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}" />
Expand All @@ -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 changes: 11 additions & 0 deletions SelectWechat.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,21 @@ public void GetWechatProcess()
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();
}
}
Expand Down
15 changes: 15 additions & 0 deletions Tools.xaml
Original file line number Diff line number Diff line change
@@ -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>
Loading

0 comments on commit 31c28d8

Please sign in to comment.