public static string GetItemText(IntPtr hwnd, int item, int subItem) { using (var hProcess = new RemoteProcessHandle(hwnd)) { int offset = hProcess.Is32Bit ? Marshal.SizeOf(typeof(LVITEM32)) : Marshal.SizeOf(typeof(LVITEM64)); int cbSize = (MAX_LVMSTRING + 1) * 2; using (var remoteMem = new RemoteMemoryHandle(hProcess, offset + cbSize)) { if (hProcess.Is32Bit) { var lvitem = new LVITEM32(); lvitem.mask = LVIF_TEXT; lvitem.pszText = (uint)(remoteMem.Address + offset); lvitem.cchTextMax = MAX_LVMSTRING; lvitem.iItem = item; lvitem.iSubItem = subItem; remoteMem.WriteTo(ref lvitem); } else { var lvitem = new LVITEM64(); lvitem.mask = LVIF_TEXT; lvitem.pszText = (ulong)(remoteMem.Address + offset); lvitem.cchTextMax = MAX_LVMSTRING; lvitem.iItem = item; lvitem.iSubItem = subItem; remoteMem.WriteTo(ref lvitem); } bool isUnicode = IsWindowUnicode(hwnd); int LVM_GETITEMTEXT = isUnicode ? LVM_GETITEMTEXTW : LVM_GETITEMTEXTA; IntPtr result = SendMessage(hwnd, LVM_GETITEMTEXT, new IntPtr(item), remoteMem.Address); if (result == IntPtr.Zero) { throw new Win32Exception(); } using (var m = new CoTaskMem(cbSize)) { remoteMem.ReadFrom(m.Address, offset, cbSize); if (isUnicode) { return(Marshal.PtrToStringUni(m.Address)); } else { return(Marshal.PtrToStringAnsi(m.Address)); } } } } }
public RemoteMemoryHandle(RemoteProcessHandle hProcess, int cbSize) : base(true) { _processHandle = hProcess; SetHandle(VirtualAllocEx(_processHandle, IntPtr.Zero, new IntPtr((uint)cbSize), MEM_COMMIT, PAGE_READWRITE)); }
private static extern bool ReadProcessMemory( RemoteProcessHandle hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, IntPtr dwSize, out IntPtr lpNumberOfBytesRead);
private static extern bool WriteProcessMemory( RemoteProcessHandle hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesWritten);
private static extern bool VirtualFreeEx(RemoteProcessHandle hProcess, IntPtr address, IntPtr size, int freeType);
private static extern IntPtr VirtualAllocEx(RemoteProcessHandle hProcess, IntPtr address, IntPtr size, int allocationType, int protect);