Explorar o código

WindowsAPI调用重构,改用SYSTEM_EXTENDED_HANDLE_INFORMATION解决

Suxue hai 1 ano
pai
achega
d4aa12cf07

+ 1 - 1
App.xaml

@@ -2,7 +2,7 @@
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:local="clr-namespace:WechatPCMsgBakTool"
-             StartupUri="Main2.xaml">
+             StartupUri="Main.xaml">
     <Application.Resources>
          
     </Application.Resources>

+ 212 - 0
Helpers/NativeAPI.cs

@@ -0,0 +1,212 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace WechatPCMsgBakTool.Helpers
+{
+    public class NativeAPI
+    {
+        // Constants
+        //=================================================
+
+        internal static uint NTSTATUS_STATUS_SUCCESS = 0x0;
+        internal static uint NTSTATUS_STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
+        internal static uint NTSTATUS_STATUS_ACCESS_DENIED = 0xC0000022;
+
+        // API Constants
+        internal static uint SystemExtendedHandleInformation = 0x40;
+        internal static uint DUPLICATE_SAME_ACCESS = 0x2;
+
+
+        // Structs
+        //=================================================
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct OBJECT_NAME_INFORMATION
+        {
+            public UNICODE_STRING Name;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct OSVERSIONINFOEX
+        {
+            public uint OSVersionInfoSize;
+            public uint MajorVersion;
+            public uint MinorVersion;
+            public uint BuildNumber;
+            public uint PlatformId;
+            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+            public string CSDVersion;
+            public ushort ServicePackMajor;
+            public ushort ServicePackMinor;
+            public ushort SuiteMask;
+            public byte ProductType;
+            public byte Reserved;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct UNICODE_STRING
+        {
+            public ushort Length;
+            public ushort MaximumLength;
+            public IntPtr Buffer;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct GENERIC_MAPPING
+        {
+            public uint GenericRead;
+            public uint GenericWrite;
+            public uint GenericExecute;
+            public uint GenericAll;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct OBJECT_TYPE_INFORMATION
+        {
+            public UNICODE_STRING TypeName;
+            public uint TotalNumberOfObjects;
+            public uint TotalNumberOfHandles;
+            public uint TotalPagedPoolUsage;
+            public uint TotalNonPagedPoolUsage;
+            public uint TotalNamePoolUsage;
+            public uint TotalHandleTableUsage;
+            public uint HighWaterNumberOfObjects;
+            public uint HighWaterNumberOfHandles;
+            public uint HighWaterPagedPoolUsage;
+            public uint HighWaterNonPagedPoolUsage;
+            public uint HighWaterNamePoolUsage;
+            public uint HighWaterHandleTableUsage;
+            public uint InvalidAttributes;
+            public GENERIC_MAPPING GenericMapping;
+            public uint ValidAccessMask;
+            public byte SecurityRequired;
+            public byte MaintainHandleCount;
+            public byte TypeIndex;
+            public byte ReservedByte;
+            public uint PoolType;
+            public uint DefaultPagedPoolCharge;
+            public uint DefaultNonPagedPoolCharge;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct OBJECT_ALL_TYPES_INFORMATION
+        {
+            public uint NumberOfObjectTypes;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct SYSTEM_HANDLE_INFORMATION_EX
+        {
+            public IntPtr NumberOfHandles;
+            public IntPtr Reserved;
+            public SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX[] Handles;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
+        {
+            public IntPtr Object;
+            public IntPtr UniqueProcessId;
+            public IntPtr HandleValue;
+            public uint GrantedAccess;
+            public ushort CreatorBackTraceIndex;
+            public ushort ObjectTypeIndex;
+            public uint HandleAttributes;
+            public uint Reserved;
+        }
+
+        // Enums
+        //=================================================
+
+        internal enum OBJECT_INFORMATION_CLASS
+        {
+            ObjectBasicInformation = 0,
+            ObjectNameInformation = 1,
+            ObjectTypeInformation = 2,
+            ObjectAllTypesInformation = 3,
+            ObjectHandleInformation = 4
+        }
+
+        internal enum POOL_TYPE
+        {
+            NonPagedPool,
+            NonPagedPoolExecute = NonPagedPool,
+            PagedPool,
+            NonPagedPoolMustSucceed = NonPagedPool + 2,
+            DontUseThisType,
+            NonPagedPoolCacheAligned = NonPagedPool + 4,
+            PagedPoolCacheAligned,
+            NonPagedPoolCacheAlignedMustS = NonPagedPool + 6,
+            MaxPoolType,
+            NonPagedPoolBase = 0,
+            NonPagedPoolBaseMustSucceed = NonPagedPoolBase + 2,
+            NonPagedPoolBaseCacheAligned = NonPagedPoolBase + 4,
+            NonPagedPoolBaseCacheAlignedMustS = NonPagedPoolBase + 6,
+            NonPagedPoolSession = 32,
+            PagedPoolSession = NonPagedPoolSession + 1,
+            NonPagedPoolMustSucceedSession = PagedPoolSession + 1,
+            DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1,
+            NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1,
+            PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1,
+            NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1,
+            NonPagedPoolNx = 512,
+            NonPagedPoolNxCacheAligned = NonPagedPoolNx + 4,
+            NonPagedPoolSessionNx = NonPagedPoolNx + 32,
+        }
+
+        internal enum PROCESS_ACCESS_FLAGS : uint
+        {
+            All = 0x001F0FFF,
+            Terminate = 0x00000001,
+            CreateThread = 0x00000002,
+            VMOperation = 0x00000008,
+            VMRead = 0x00000010,
+            VMWrite = 0x00000020,
+            DupHandle = 0x00000040,
+            SetInformation = 0x00000200,
+            QueryInformation = 0x00000400,
+            Synchronize = 0x00100000
+        }
+
+        // API
+        //=================================================
+
+        [DllImport("kernel32.dll")]
+        internal static extern bool CloseHandle(IntPtr hObject);
+
+        [DllImport("ntdll.dll")]
+        internal static extern uint RtlGetVersion(
+            ref OSVERSIONINFOEX VersionInformation);
+
+        [DllImport("ntdll.dll")]
+        internal static extern void RtlZeroMemory(
+            IntPtr Destination,
+            uint length);
+
+        [DllImport("ntdll.dll")]
+        internal static extern uint NtQueryObject(
+            IntPtr objectHandle,
+            OBJECT_INFORMATION_CLASS informationClass,
+            IntPtr informationPtr,
+            uint informationLength,
+            ref uint returnLength);
+
+        [DllImport("ntdll.dll")]
+        internal static extern uint NtQuerySystemInformation(
+            uint SystemInformationClass,
+            IntPtr SystemInformation,
+            uint SystemInformationLength,
+            ref uint ReturnLength);
+
+
+        [DllImport("kernel32.dll")]
+        internal static extern IntPtr OpenProcess(PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
+
+        [DllImport("kernel32.dll", SetLastError = true)]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
+
+        [DllImport("kernel32.dll")]
+        internal static extern IntPtr GetCurrentProcess();
+    }
+}

+ 151 - 0
Helpers/NativeAPIHelper.cs

@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using static WechatPCMsgBakTool.Helpers.NativeAPI;
+
+namespace WechatPCMsgBakTool.Helpers
+{
+    public class NativeAPIHelper
+    {
+        // Managed native buffer
+        internal static IntPtr AllocManagedMemory(uint iSize)
+        {
+            IntPtr pAlloc = Marshal.AllocHGlobal((int)iSize);
+            RtlZeroMemory(pAlloc, iSize);
+
+            return pAlloc;
+        }
+
+        // Free managed buffer
+        internal static bool FreeManagedMemory(IntPtr pAlloc)
+        {
+            Marshal.FreeHGlobal(pAlloc);
+
+            return true;
+        }
+
+        // Get an array of OBJECT_ALL_TYPES_INFORMATION, describing all object types
+        // Win8+ only
+        internal static string FindHandleName(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX systemHandleInformation, Process process)
+        {
+            IntPtr ipHandle = IntPtr.Zero;
+            IntPtr openProcessHandle = IntPtr.Zero;
+            IntPtr hObjectName = IntPtr.Zero;
+            try
+            {
+                PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead;
+                openProcessHandle = OpenProcess(flags, false, process.Id);
+                // 通过 DuplicateHandle 访问句柄
+                if (!DuplicateHandle(openProcessHandle, systemHandleInformation.HandleValue, GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS))
+                {
+                    return "";
+                }
+
+                uint nLength = 0;
+                hObjectName = AllocManagedMemory(256 * 1024);
+
+                // 查询句柄名称
+                while (NtQueryObject(ipHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength) == NTSTATUS_STATUS_INFO_LENGTH_MISMATCH)
+                {
+                    FreeManagedMemory(hObjectName);
+                    if (nLength == 0)
+                    {
+                        Console.WriteLine("Length returned at zero!");
+                        return "";
+                    }
+                    hObjectName = AllocManagedMemory(nLength);
+                }
+                OBJECT_NAME_INFORMATION? objObjectName = new OBJECT_NAME_INFORMATION();
+                objObjectName = Marshal.PtrToStructure(hObjectName, objObjectName.GetType()) as OBJECT_NAME_INFORMATION?;
+                if (objObjectName == null)
+                    return "";
+                if (objObjectName.Value.Name.Buffer != IntPtr.Zero)
+                {
+                    string? strObjectName = Marshal.PtrToStringUni(objObjectName.Value.Name.Buffer);
+                    if (strObjectName != null)
+                        return strObjectName;
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.Message);
+            }
+            finally
+            {
+                FreeManagedMemory(hObjectName);
+                CloseHandle(ipHandle);
+                CloseHandle(openProcessHandle);
+            }
+            return "";
+        }
+
+        internal static List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> GetHandleInfoForPID(uint ProcId)
+        {
+            // Create return object
+            List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> ltei = new List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX>();
+
+            // Create Buffer variable
+            IntPtr BuffPtr = IntPtr.Zero;
+
+            // Loop till success
+            uint LoopSize = 0;
+            while (true)
+            {
+                BuffPtr = AllocManagedMemory(LoopSize);
+                uint SystemInformationLength = 0;
+                uint CallRes = NtQuerySystemInformation(SystemExtendedHandleInformation, BuffPtr, LoopSize, ref SystemInformationLength);
+                if (CallRes == NTSTATUS_STATUS_INFO_LENGTH_MISMATCH)
+                {
+                    FreeManagedMemory(BuffPtr);
+                    LoopSize = Math.Max(LoopSize, SystemInformationLength);
+                }
+                else if (CallRes == NTSTATUS_STATUS_SUCCESS)
+                {
+                    break;
+                }
+                else if (CallRes == NTSTATUS_STATUS_ACCESS_DENIED)
+                {
+                    FreeManagedMemory(BuffPtr);
+                    throw new AccessViolationException("[!] Failed to query SystemExtendedHandleInformation: Access Denied");
+                }
+                else
+                {
+                    FreeManagedMemory(BuffPtr);
+                    throw new InvalidOperationException("[!] Failed to query SystemExtendedHandleInformation.");
+                }
+            }
+
+            // Read handle count
+            Int32 HandleCount = Marshal.ReadInt32(BuffPtr);
+
+            // Move Buff ptr
+            BuffPtr = (IntPtr)(BuffPtr.ToInt64() + (IntPtr.Size * 2));
+
+            // Loop handles
+            for (int i = 0; i < HandleCount; i++)
+            {
+                ulong iCurrProcId = (ulong)Marshal.ReadIntPtr((IntPtr)(BuffPtr.ToInt64() + IntPtr.Size));
+                if (ProcId == iCurrProcId)
+                {
+                    // Ptr -> SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
+                    SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX? tei = (SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX?)Marshal.PtrToStructure(BuffPtr, typeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX));
+
+                    if (tei == null)
+                        continue;
+                    else
+                        ltei.Add(tei.Value);
+                }
+
+                // Move Buffptr
+                BuffPtr = (IntPtr)(BuffPtr.ToInt64() + Marshal.SizeOf(typeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX)));
+            }
+
+            // Return list
+            return ltei;
+        }
+    }
+}

+ 4 - 163
Helpers/ProcessHelper.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.IO;
 using System.Linq;
 using System.Net.NetworkInformation;
 using System.Runtime.InteropServices;
@@ -12,12 +13,8 @@ namespace WechatPCMsgBakTool.Helpers
 {
     public class ProcessHelper
     {
-        private const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
-        private const int DUPLICATE_SAME_ACCESS = 0x2;
-
-        private const int CNST_SYSTEM_HANDLE_INFORMATION = 0x10;
-
-        public static Process GetProcess(string ProcessName)
+        
+        public static Process? GetProcess(string ProcessName)
         {
             Process[] processes = Process.GetProcessesByName(ProcessName);
             if (processes.Length == 0)
@@ -83,99 +80,6 @@ namespace WechatPCMsgBakTool.Helpers
             return offset;
         }
 
-        public static List<SYSTEM_HANDLE_INFORMATION> GetHandles(Process process)
-        {
-            List<SYSTEM_HANDLE_INFORMATION> aHandles = new List<SYSTEM_HANDLE_INFORMATION>();
-            int handle_info_size = Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION()) * 20000;
-            IntPtr ptrHandleData = IntPtr.Zero;
-            try
-            {
-                ptrHandleData = Marshal.AllocHGlobal(handle_info_size);
-                int nLength = 0;
-
-                while (NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ptrHandleData, handle_info_size, ref nLength) == STATUS_INFO_LENGTH_MISMATCH)
-                {
-                    handle_info_size = nLength;
-                    Marshal.FreeHGlobal(ptrHandleData);
-                    ptrHandleData = Marshal.AllocHGlobal(nLength);
-                }
-
-                long handle_count = Marshal.ReadIntPtr(ptrHandleData).ToInt64();
-                IntPtr ptrHandleItem = ptrHandleData + Marshal.SizeOf(ptrHandleData);
-
-                for (long lIndex = 0; lIndex < handle_count; lIndex++)
-                {
-                    SYSTEM_HANDLE_INFORMATION? oSystemHandleInfo = new SYSTEM_HANDLE_INFORMATION();
-                    oSystemHandleInfo = Marshal.PtrToStructure(ptrHandleItem, oSystemHandleInfo.GetType()) as SYSTEM_HANDLE_INFORMATION?;
-                    if (oSystemHandleInfo == null)
-                        throw new Exception("获取SYSTEM_HANDLE_INFORMATION失败");
-                    ptrHandleItem += Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION());
-                    if (oSystemHandleInfo.Value.ProcessID != process.Id) { continue; }
-                    aHandles.Add(oSystemHandleInfo.Value);
-                }
-            }
-            catch (Exception)
-            {
-                throw;
-            }
-            finally
-            {
-                Marshal.FreeHGlobal(ptrHandleData);
-            }
-            return aHandles;
-        }
-        public static string FindHandleName(SYSTEM_HANDLE_INFORMATION systemHandleInformation, Process process)
-        {
-            IntPtr ipHandle = IntPtr.Zero;
-            IntPtr openProcessHandle = IntPtr.Zero;
-            IntPtr hObjectName = IntPtr.Zero;
-            try
-            {
-                PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead;
-                openProcessHandle = OpenProcess(flags, false, process.Id);
-                // 通过 DuplicateHandle 访问句柄
-                if (!DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS))
-                {
-                    return "";
-                }
-
-                int nLength = 0;
-                hObjectName = Marshal.AllocHGlobal(256 * 1024);
-
-                // 查询句柄名称
-                while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
-                {
-                    Marshal.FreeHGlobal(hObjectName);
-                    if (nLength == 0)
-                    {
-                        Console.WriteLine("Length returned at zero!");
-                        return "";
-                    }
-                    hObjectName = Marshal.AllocHGlobal(nLength);
-                }
-                OBJECT_NAME_INFORMATION? objObjectName = new OBJECT_NAME_INFORMATION();
-                objObjectName = Marshal.PtrToStructure(hObjectName, objObjectName.GetType()) as OBJECT_NAME_INFORMATION?;
-                if (objObjectName == null)
-                    return "";
-                if (objObjectName.Value.Name.Buffer != IntPtr.Zero)
-                {
-                    string? strObjectName = Marshal.PtrToStringUni(objObjectName.Value.Name.Buffer);
-                    if (strObjectName != null)
-                        return strObjectName;
-                }
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine(ex.Message);
-            }
-            finally
-            {
-                Marshal.FreeHGlobal(hObjectName);
-                CloseHandle(ipHandle);
-                CloseHandle(openProcessHandle);
-            }
-            return "";
-        }
         // 这里开始下面是对Windows API引用声明
         public static byte[]? ReadMemoryDate(IntPtr hProcess, IntPtr lpBaseAddress, int nSize = 100)
         {
@@ -189,70 +93,7 @@ namespace WechatPCMsgBakTool.Helpers
 
         [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);
-
-        [DllImport("kernel32.dll")]
-        private static extern IntPtr OpenProcess(PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
-
-        [DllImport("kernel32.dll", SetLastError = true)]
-        [return: MarshalAs(UnmanagedType.Bool)]
-        private static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
-
-        [DllImport("kernel32.dll")]
-        private static extern IntPtr GetCurrentProcess();
-
-        [DllImport("ntdll.dll")]
-        private static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength);
-
-        [DllImport("kernel32.dll")]
-        private static extern bool CloseHandle(IntPtr hObject);
-
-        [StructLayout(LayoutKind.Sequential, Pack = 1)]
-        public struct SYSTEM_HANDLE_INFORMATION
-        { // Information Class 16
-            public ushort ProcessID;
-            public ushort CreatorBackTrackIndex;
-            public byte ObjectType;
-            public byte HandleAttribute;
-            public ushort Handle;
-            public IntPtr Object_Pointer;
-            public IntPtr AccessMask;
-        }
-        private enum OBJECT_INFORMATION_CLASS : int
-        {
-            ObjectBasicInformation = 0,
-            ObjectNameInformation = 1,
-            ObjectTypeInformation = 2,
-            ObjectAllTypesInformation = 3,
-            ObjectHandleInformation = 4
-        }
-        [StructLayout(LayoutKind.Sequential, Pack = 1)]
-        private struct OBJECT_NAME_INFORMATION
-        {
-            public UNICODE_STRING Name;
-        }
-        [StructLayout(LayoutKind.Sequential)]
-        private struct UNICODE_STRING
-        {
-            public ushort Length;
-            public ushort MaximumLength;
-            public IntPtr Buffer;
-        }
-        [Flags]
-        private enum PROCESS_ACCESS_FLAGS : uint
-        {
-            All = 0x001F0FFF,
-            Terminate = 0x00000001,
-            CreateThread = 0x00000002,
-            VMOperation = 0x00000008,
-            VMRead = 0x00000010,
-            VMWrite = 0x00000020,
-            DupHandle = 0x00000040,
-            SetInformation = 0x00000200,
-            QueryInformation = 0x00000400,
-            Synchronize = 0x00100000
-        }
+        
     }
 
 }

+ 0 - 1
Main.xaml

@@ -38,6 +38,5 @@
         <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"/>
-        <Button Content="Button" HorizontalAlignment="Left" Margin="626,0,0,0" VerticalAlignment="Center" Click="Button_Click_2"/>
     </Grid>
 </Window>

+ 26 - 1
Pages/Workspace.xaml

@@ -49,6 +49,26 @@
                 <Label Margin="60,25,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="140" Content="{Binding LastMsg}"/>
             </Grid>
         </DataTemplate>
+        <DataTemplate x:Key="MsgText">
+            <Grid Margin="0">
+                <Label Margin="60,8,0,0" FontWeight="Bold" VerticalAlignment="Top" HorizontalAlignment="Left" Content="{Binding NickName}" Width="130"/>
+                <Label Margin="60,25,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="140" Content="{Binding LastMsg}"/>
+            </Grid>
+        </DataTemplate>
+        <DataTemplate x:Key="MsgImage">
+            <Grid Margin="0">
+                <Image Width="40" Height="40" Margin="10" VerticalAlignment="Top" HorizontalAlignment="Left" Source="{Binding Avatar}"  />
+                <Label Margin="60,8,0,0" FontWeight="Bold" VerticalAlignment="Top" HorizontalAlignment="Left" Content="{Binding NickName}" Width="130"/>
+                <Label Margin="60,25,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="140" Content="{Binding LastMsg}"/>
+            </Grid>
+        </DataTemplate>
+        <DataTemplate x:Key="MsgAudio">
+            <Grid Margin="0">
+                <Image Width="40" Height="40" Margin="10" VerticalAlignment="Top" HorizontalAlignment="Left" Source="{Binding Avatar}"  />
+                <Label Margin="60,8,0,0" FontWeight="Bold" VerticalAlignment="Top" HorizontalAlignment="Left" Content="{Binding NickName}" Width="130"/>
+                <Label Margin="60,25,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="140" Content="{Binding LastMsg}"/>
+            </Grid>
+        </DataTemplate>
     </Page.Resources>
     <Grid>
         <!--
@@ -105,6 +125,11 @@
             </ListView.Resources>
         </ListView>
         <Label Content="{Binding WXContact.UserName}" HorizontalAlignment="Left" Margin="258,21,0,0" VerticalAlignment="Top"/>
-
+        <ListView x:Name="list_msg" Margin="230,60,0,0" Background="Aqua" BorderThickness="0">
+            <Grid Margin="0">
+                <Label Margin="0,8,0,0" FontWeight="Bold" VerticalAlignment="Top" Content="溯雪" Width="130"/>
+                <Label Margin="60,25,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="140" Content="{Binding LastMsg}"/>
+            </Grid>
+        </ListView>
     </Grid>
 </Page>

+ 6 - 0
Pages/Workspace.xaml.cs

@@ -55,6 +55,12 @@ namespace WechatPCMsgBakTool.Pages
         private void list_users_SelectionChanged(object sender, SelectionChangedEventArgs e)
         {
             ViewModel.WXContact = list_users.SelectedItem as WXContact;
+            if(ViewModel.WXContact == null || UserReader == null)
+            {
+                return;
+            }
+            List<WXMsg>? msgs = UserReader.GetWXMsgs(ViewModel.WXContact.UserName);
+            ListViewItem i = new ListViewItem();
         }
 
         private void txt_find_user_TextChanged(object sender, TextChangedEventArgs e)

+ 6 - 4
SelectWechat.xaml.cs

@@ -42,16 +42,18 @@ namespace WechatPCMsgBakTool
             Process[] processes = Process.GetProcessesByName("wechat");
             foreach (Process p in processes)
             {
-                var h_list = ProcessHelper.GetHandles(p);
-                foreach (var h in h_list)
+                File.AppendAllText("debug.log", "wechat=>" + p.Id + "\r\n");
+                var lHandles = NativeAPIHelper.GetHandleInfoForPID((uint)p.Id);
+                
+                foreach (var h in lHandles)
                 {
-                    string name = ProcessHelper.FindHandleName(h, p);
+                    string name = NativeAPIHelper.FindHandleName(h, p);
                     if (name != "")
                     {
                         // 预留handle log
                         if (File.Exists("handle.log"))
                         {
-                            File.AppendAllText("handle.log", string.Format("{0}|{1}|{2}|{3}\n", p.Id, h.ObjectType, h.Handle, name));
+                            File.AppendAllText("handle.log", string.Format("{0}|{1}|{2}|{3}\n", p.Id, h.ObjectTypeIndex, h.HandleValue, name));
                         }
                         if (name.Contains("\\MicroMsg.db") && name.Substring(name.Length - 3, 3) == ".db")
                         {

+ 3 - 3
WechatPCMsgBakTool.csproj

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