Browse Source

新增公钥头推断查找

Suxue 1 năm trước cách đây
mục cha
commit
cf7d75625d

+ 55 - 7
Helpers/DecryptionHelper.cs

@@ -26,7 +26,7 @@ namespace WechatBakTool.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(string pid, bool mem_find_key, string account)
+        public static byte[]? GetWechatKey(string pid, int find_key_type, string account)
         {
             Process process = Process.GetProcessById(int.Parse(pid));
             ProcessModule? module = ProcessHelper.FindProcessModule(process.Id, "WeChatWin.dll");
@@ -40,9 +40,7 @@ namespace WechatBakTool.Helpers
                 return null;
             }
 
-
-
-            if (!mem_find_key)
+            if (find_key_type == 1)
             {
                 List<VersionInfo>? info = null;
                 string json = File.ReadAllText("version.json");
@@ -69,29 +67,79 @@ namespace WechatBakTool.Helpers
                     }
                 }
             }
-            else
+            else if(find_key_type == 2)
             {
                 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 _))
+                    if (NativeAPI.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 _))
+                        if (NativeAPI.ReadProcessMemory(process.Handle, (IntPtr)addr, key_bytes, key_bytes.Length, out _))
                         {
                             return key_bytes;
                         }
                     }
                 }
+            }
+            else if (find_key_type == 3)
+            {
+                string searchString = "-----BEGIN PUBLIC KEY-----";
+                List<long> addr = NativeAPIHelper.SearchProcessAllMemory(process, searchString);
+                if (addr.Count > 0)
+                {
+                    foreach (long a in addr)
+                    {
+                        byte[] buffer = new byte[module.ModuleMemorySize];
+                        byte[] search = BitConverter.GetBytes(a);
+                        Array.Resize(ref search, 8);
+                        int read = 0;
+
+                        List<int> offset = new List<int>();
+                        if (NativeAPI.ReadProcessMemory(process.Handle, module.BaseAddress, buffer, buffer.Length, out read))
+                        {
+                            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)
+                                        {
+                                            long iii = (long)module.BaseAddress + i - 0xd8;
+
+                                            byte[] key = new byte[8];
+                                            if (NativeAPI.ReadProcessMemory(process.Handle, new IntPtr(iii), key, key.Length, out _))
+                                            {
+                                                ulong key_addr = BitConverter.ToUInt64(key, 0);
+
+                                                byte[] key_bytes = new byte[32];
+                                                NativeAPI.ReadProcessMemory(process.Handle, (IntPtr)key_addr, key_bytes, key_bytes.Length, out _);
+                                                string key1 = BitConverter.ToString(key_bytes, 0);
+                                                return key_bytes;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
                 else
                 {
                     throw new Exception("搜索不到微信账号,请确认用户名是否正确,如错误请重新新建工作区,务必确认账号是否正确");
                 }
             }
+            else if (find_key_type == 3)
+            {
+                string searchString = "-----BEGIN PUBLIC KEY-----";
+            }
             return null;
         }
 

+ 27 - 0
Helpers/NativeAPI.cs

@@ -12,6 +12,12 @@ namespace WechatBakTool.Helpers
         internal static uint NTSTATUS_STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
         internal static uint NTSTATUS_STATUS_ACCESS_DENIED = 0xC0000022;
 
+        internal static uint MEM_COMMIT = 0x1000;
+        internal static uint PAGE_READONLY = 0x02;
+        internal static uint PAGE_READWRITE = 0x04;
+        internal static uint PAGE_EXECUTE = 0x10;
+        internal static uint PAGE_EXECUTE_READ = 0x20;
+
         // API Constants
         internal static uint SystemExtendedHandleInformation = 0x40;
         internal static uint DUPLICATE_SAME_ACCESS = 0x2;
@@ -115,6 +121,20 @@ namespace WechatBakTool.Helpers
             public uint Reserved;
         }
 
+
+        public struct MEMORY_BASIC_INFORMATION64
+        {
+            public IntPtr BaseAddress;
+            public IntPtr AllocationBase;
+            public uint AllocationProtect;
+            public uint __alignment1;
+            public ulong RegionSize;
+            public uint State;
+            public uint Protect;
+            public uint Type;
+            public uint __alignment2;
+        }
+
         // Enums
         //=================================================
 
@@ -208,5 +228,12 @@ namespace WechatBakTool.Helpers
 
         [DllImport("kernel32.dll")]
         internal static extern IntPtr GetCurrentProcess();
+
+        [DllImport("kernel32.dll")]
+        internal static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION64 lpBuffer, uint dwLength);
+
+        [DllImport("kernel32.dll", SetLastError = true)]
+        internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int nSize, out int lpNumberOfBytesRead);
+
     }
 }

+ 47 - 0
Helpers/NativeAPIHelper.cs

@@ -149,5 +149,52 @@ namespace WechatBakTool.Helpers
             // Return list
             return ltei;
         }
+
+        public static List<long> SearchProcessAllMemory(Process process, string searchString)
+        {
+            IntPtr minAddress = IntPtr.Zero;
+            IntPtr maxAddress = IntPtr.MaxValue;
+            List<long> addrList = new List<long>();
+
+            while (minAddress.ToInt64() < maxAddress.ToInt64())
+            {
+                MEMORY_BASIC_INFORMATION64 memInfo;
+                int result = VirtualQueryEx(process.Handle, minAddress, out memInfo, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION64)));
+
+                if (result == 0)
+                {
+                    break;
+                }
+
+                if (memInfo.State == MEM_COMMIT && (memInfo.Protect == PAGE_EXECUTE || memInfo.Protect == PAGE_EXECUTE_READ || memInfo.Protect == PAGE_EXECUTE_READ || memInfo.Protect == PAGE_READWRITE || memInfo.Protect == PAGE_READONLY))
+                {
+                    byte[] buffer = new byte[(long)memInfo.RegionSize];
+                    bool success = ReadProcessMemory(process.Handle, memInfo.BaseAddress, buffer, buffer.Length, out _);
+
+                    if (success)
+                    {
+                        byte[] search = Encoding.ASCII.GetBytes(searchString);
+                        for (int i = 0; i < buffer.Length - 8; 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)
+                                    {
+                                        addrList.Add((long)memInfo.BaseAddress + i);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                minAddress = new IntPtr(memInfo.BaseAddress.ToInt64() + (long)memInfo.RegionSize);
+            }
+            return addrList;
+        }
+
     }
 }

+ 2 - 4
Helpers/ProcessHelper.cs

@@ -32,7 +32,7 @@ namespace WechatBakTool.Helpers
 
             List<int> offset = new List<int>();
             int readBytes;
-            bool success = ReadProcessMemory(processHandle, module.BaseAddress, buffer, buffer.Length,out readBytes);
+            bool success = NativeAPI.ReadProcessMemory(processHandle, module.BaseAddress, buffer, buffer.Length,out readBytes);
 
             if (!success || readBytes == 0)
             {
@@ -64,14 +64,12 @@ namespace WechatBakTool.Helpers
         {
             byte[] array = new byte[nSize];
             int readByte;
-            if (!ReadProcessMemory(hProcess, lpBaseAddress, array, nSize, out readByte))
+            if (!NativeAPI.ReadProcessMemory(hProcess, lpBaseAddress, array, nSize, out readByte))
                 return null;
             else
                 return array;
         }
 
-        [DllImport("kernel32.dll", SetLastError = true)]
-        public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int nSize, out int lpNumberOfBytesRead);
         
     }
 

+ 3 - 2
Pages/CreateWork.xaml

@@ -26,8 +26,9 @@
         <TextBox IsEnabled="{Binding IsEnable}" x:Name="txt_username" Margin="35,300,0,0" Width="280" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="0,0,0,1" Text="{Binding UserName}" />
 
         <Label Margin="30,350,0,0" Content="请选择解密方式:" FontWeight="Bold" HorizontalAlignment="Left" VerticalAlignment="Top"/>
-        <RadioButton Margin="35,380,0,0" Content="固定地址查找" HorizontalAlignment="Left" VerticalAlignment="Top" GroupName="rb_find_key" HorizontalContentAlignment="Center" IsEnabled="{Binding IsEnable}" VerticalContentAlignment="Center" IsChecked="{Binding KeyType, Converter={StaticResource ResourceKey=getKeyConverterKey}, ConverterParameter=1}" />
-        <RadioButton Margin="35,405,0,0" Content="用户名推断查找" HorizontalAlignment="Left" VerticalAlignment="Top" GroupName="rb_find_key" HorizontalContentAlignment="Center" IsEnabled="{Binding IsEnable}" VerticalContentAlignment="Center" IsChecked="{Binding KeyType, Converter={StaticResource ResourceKey=getKeyConverterKey}, ConverterParameter=2}"/>
+        <RadioButton Margin="35,380,0,0" Content="固定地址查找【保底】" HorizontalAlignment="Left" VerticalAlignment="Top" GroupName="rb_find_key" HorizontalContentAlignment="Center" IsEnabled="{Binding IsEnable}" VerticalContentAlignment="Center" IsChecked="{Binding KeyType, Converter={StaticResource ResourceKey=getKeyConverterKey}, ConverterParameter=1}" />
+        <RadioButton Margin="35,405,0,0" Content="用户名推断查找【不稳定】" HorizontalAlignment="Left" VerticalAlignment="Top" GroupName="rb_find_key" HorizontalContentAlignment="Center" IsEnabled="{Binding IsEnable}" VerticalContentAlignment="Center" IsChecked="{Binding KeyType, Converter={StaticResource ResourceKey=getKeyConverterKey}, ConverterParameter=2}"/>
+        <RadioButton Margin="35,430,0,0" Content="公钥头推断查找【推荐】" HorizontalAlignment="Left" VerticalAlignment="Top" GroupName="rb_find_key" HorizontalContentAlignment="Center" IsEnabled="{Binding IsEnable}" VerticalContentAlignment="Center" IsChecked="{Binding KeyType, Converter={StaticResource ResourceKey=getKeyConverterKey}, ConverterParameter=3}"/>
 
         <Button Name="btn_create_worksapce" Margin="0,0,35,50" Height="60" Width="100" HorizontalAlignment="Right" VerticalAlignment="Bottom" Content="创建工作区" BorderThickness="0" IsEnabled="{Binding IsEnable}" Background="#2775b6" Foreground="White" Click="btn_create_worksapce_Click">
             <Button.Resources>

+ 3 - 2
WXWorkspace.cs

@@ -38,12 +38,13 @@ namespace WechatBakTool
             if (!UserBakConfig.Decrypt)
             {
                 byte[]? key = null;
-                key = DecryptionHelper.GetWechatKey(pid, type == 2, UserBakConfig.Account);
+                viewModel.LabelStatus = "正在获取秘钥,需要1 - 10秒左右";
+                key = DecryptionHelper.GetWechatKey(pid, type, UserBakConfig.Account);
                 if (key == null)
                 {
                     throw new Exception("获取到的密钥为空,获取失败");
                 }
-                string key_string = BitConverter.ToString(key, 0).Replace("-", string.Empty).ToLower().ToUpper();
+
                 string source = Path.Combine(UserBakConfig.UserWorkspacePath, "OriginalDB");
                 string to = Path.Combine(UserBakConfig.UserWorkspacePath, "DecDB");