Как получить список ListView чужого процесса

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Как получить список ListView чужого процесса

Сообщение Vova_2581 » 09.02.2023 (Чт) 20:01

Здравствуйте!
Возникла производственная необходимость получить список всех элементов ListView в чужом процессе. Вкратце... есть сервер, на нем программа управления со списком ListView всех подключенных клиентов, то бишь студентов и преподавателей. Мне нужно получить данные этого списка и выделить только студентов. Показать список только студентов в своем окне и все! Больше ничего не нужно. Прежде, чем обратиться сюда долго пытался сделать это сам, но ничего не получилось, кроме, как получить просто количество элементов... но это почти ничего... (((
Код: Выделить всё
Private Declare Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "User32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Long
Private Const LVM_FIRST = &H1000
Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
Private Const LVM_GETITEMTEXT = (LVM_FIRST + 45)

Private Sub Form_Load()
Dim hHost As Long
Dim hPanel As Long
Dim hPanel2 As Long
Dim hListView As Long
Dim lCount As Long

'Находим наш ListView на главной форме сервера...
hHost = FindWindow("TF_Main", vbNullString)
hPanel = FindWindowEx(hHost, ByVal 0&, "TPanel", vbNullString)
hPanel2 = FindWindowEx(hHost, hPanel, "TPanel", vbNullString)
hListView = FindWindowEx(hPanel2, ByVal 0&, "TListView", vbNullString)
'Количество элементов списка...
lCount = SendMessage(hListView, LVM_GETITEMCOUNT, 0&, 0&)
MsgBox lCount
End Sub

...а дальше начинаются выкрутасы с памятью чужого процесса, но я в этом не силен. Искал примеры здесь...
http://bbs.vbstreets.ru/viewtopic.php?f=1&t=35356
https://forum.sources.ru/index.php?showtopic=314667
но проблема не решена... а здесь...
http://bbs.vbstreets.ru/viewtopic.php?p=6712105#p6712105
у автора GDK все получилось, но листинг он так и не выложил. ((( Писать автору топика не решился в силу давности публикации за февраль 2009 года. Наверное никто уже и не ответит мне. (((

Нашел пример на С вот здесь...
https://www.codeproject.com/Articles/5570/Stealing-Program-s-Memory
Автор статьи анализирует неправильный код и в конце пишет, что все исправил и все получилось...
(цитата)
«Yay, all done. In case that didn't make too much sense to you, here is our new code, all fixed up.»
«Ура, все готово. В случае, если это не имеет для вас особого смысла, вот наш новый код, все исправлено.»

Но я не знаю С и не могу перевести этот код на бейсик. Просьба помочь, очень нужно для работы.

Пробовал и такие варианты...
Код: Выделить всё
Private Declare Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "User32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Long
Private Const LVM_FIRST = &H1000
Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
Private Const LVM_GETITEMTEXT = (LVM_FIRST + 45)

Private Type LVITEM
    mask       As Long
    iItem      As Long
    iSubItem   As Long
    State      As Long
    stateMask  As Long
    pszText    As Long
    cchTextMax As Long
    iImage     As Long
    lParam     As Long
    iIndent    As Long
End Type

Private Declare Function GetWindowThreadProcessId Lib "User32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Const PROCESS_VM_OPERATION = &H8
Private Const PROCESS_VM_READ = &H10
Private Const PROCESS_VM_WRITE = &H20
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Declare Function VirtualAllocEx Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpAddress As Any, ByRef dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Const MEM_COMMIT = &H1000
Private Const PAGE_READWRITE = &H4
Private Declare Function VirtualFreeEx Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpAddress As Any, ByRef dwSize As Long, ByVal dwFreeType As Long) As Long
Private Const MEM_RELEASE = &H8000
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal Handle As Long) As Long

Private Sub Form_Load()
Dim hHost As Long
Dim hPanel As Long
Dim hPanel2 As Long
Dim hListView As Long
Dim lCount As Long

'Находим наш ListView на главной форме сервера...
hHost = FindWindow("TF_Main", vbNullString)
hPanel = FindWindowEx(hHost, ByVal 0&, "TPanel", vbNullString)
hPanel2 = FindWindowEx(hHost, hPanel, "TPanel", vbNullString)
hListView = FindWindowEx(hPanel2, ByVal 0&, "TListView", vbNullString)
'Количество элементов списка...
lCount = SendMessage(hListView, LVM_GETITEMCOUNT, 0&, 0&)
MsgBox lCount

Dim PID As Long
Dim hProcess As Long
Dim LVTextBufferAddr As Long
GetWindowThreadProcessId hListView, PID
hProcess = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or _
                        PROCESS_VM_WRITE Or PROCESS_QUERY_INFORMATION, False, PID)

LVTextBufferAddr = VirtualAllocEx(hProcess, ByVal 0&, ByVal 512&, MEM_COMMIT, PAGE_READWRITE)

Dim uLVI As LVITEM
Dim a(512) As Byte
Dim lLen   As Long
With uLVI
.mask = LVIF_TEXT
.iItem = 1
.iSubItem = 1
.pszText = LVTextBufferAddr
.cchTextMax = 512
End With
lLen = SendMessage(hListView, LVM_GETITEMTEXT, 1, VarPtr(uLVI))
ItemText = Left$(StrConv(a(), vbUnicode), lLen)
MsgBox ItemText

VirtualFreeEx hProcess, LVTextBufferAddr, 0&, MEM_RELEASE
CloseHandle hProcess
End Sub


Но глухо, пока ничего... (((

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Как получить список ListView чужого процесса

Сообщение Teranas » 09.02.2023 (Чт) 20:20

Сам процесс не нужен, только hwnd ListView

Код: Выделить всё
Public Sub ListView_GetItemText(hwndLV As Long, i As Long, iSubItem As Long, _
                                                     pszText As Long, cchTextMax As Long)
  Dim lvi As LVITEM
  lvi.iSubItem = iSubItem
  lvi.cchTextMax = cchTextMax
  lvi.pszText = pszText
  SendMessage hwndLV, LVM_GETITEMTEXT, ByVal i, lvi
  pszText = lvi.pszText   ' fills pszText w/ pointer
End Sub

Public Sub ListView_SetItemText(hwndLV As Long, i As Long, iSubItem As Long, pszText As Long)
  Dim lvi As LVITEM
  lvi.iSubItem = iSubItem
  lvi.pszText = pszText
  SendMessage hwndLV, LVM_SETITEMTEXT, ByVal i, lvi
End Sub

Public Sub ListView_SetItemCount(hwndLV As Long, cItems As Long)
  SendMessage hwndLV, LVM_SETITEMCOUNT, ByVal cItems, 0
End Sub

С уважением, Андрей.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как получить список ListView чужого процесса

Сообщение The trick » 09.02.2023 (Чт) 21:50

UA6527P

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как получить список ListView чужого процесса

Сообщение Vova_2581 » 10.02.2023 (Пт) 12:14

Teranas
По всей видимости мне нужен только этот Sub... Ну как то это вырвано из контекста, не уверен, что пойдет.
Есть вопрос: с этим hwndLV понятно, с этим i, cchTextMax тоже. А что должно быть в iSubItem и pszText ???

Код: Выделить всё
Public Sub ListView_GetItemText(hwndLV As Long, i As Long, iSubItem As Long, _
                                                     pszText As Long, cchTextMax As Long)
  Dim lvi As LVITEM
  lvi.iSubItem = iSubItem
  lvi.cchTextMax = cchTextMax
  lvi.pszText = pszText
  SendMessage hwndLV, LVM_GETITEMTEXT, ByVal i, lvi
  pszText = lvi.pszText   ' fills pszText w/ pointer
End Sub


К тому же, я уже проходил это SendMessage hwndLV, LVM_GETITEMTEXT, ByVal i, lvi и получал по рукам от компилятора за некорректно переданный lvi, ну типа должен быть указан указатель на память или что-то типа того, скорее всего тут будет тоже самое.

The trick
Ок. гляну, потом напишу...

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Как получить список ListView чужого процесса

Сообщение Teranas » 10.02.2023 (Пт) 13:38

Какие проблемы, тогда надо учить VB и varptr()

И соответственно поменять

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

на

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
С уважением, Андрей.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как получить список ListView чужого процесса

Сообщение Vova_2581 » 10.02.2023 (Пт) 16:09

Teranas
А, так я уже это делал... в последнем коде. Ок. я попробую переделать по вашему примеру.
The trick
Интересный код, но все... и там же... как и везде крутиться вокруг работы с памятью чужого процесса.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как получить список ListView чужого процесса

Сообщение The trick » 10.02.2023 (Пт) 17:06

Vova_2581 писал(а):Teranas
А, так я уже это делал... в последнем коде. Ок. я попробую переделать по вашему примеру.
The trick
Интересный код, но все... и там же... как и везде крутиться вокруг работы с памятью чужого процесса.

https://learn.microsoft.com/en-us/windo ... endmessage
The system only does marshalling for system messages (those in the range 0 to (WM_USER-1)). To send other messages (those >= WM_USER) to another process, you must do custom marshalling.

А теперь смотри сообщение LVM_GETITEMTEXT:
Код: Выделить всё
#define WM_USER                         0x0400

#define LVM_GETITEMTEXTA        (LVM_FIRST + 45)
#define LVM_GETITEMTEXTW        (LVM_FIRST + 115)

#ifdef UNICODE
#define  LVM_GETITEMTEXT        LVM_GETITEMTEXTW
#else
#define  LVM_GETITEMTEXT        LVM_GETITEMTEXTA
#endif

#define LVM_FIRST               0x1000

Получается что без ручного маршалинга ты не вызовешь и придется выделять память в чужом процессе, либо мапить ее.
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как получить список ListView чужого процесса

Сообщение Хакер » 11.02.2023 (Сб) 9:24

—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как получить список ListView чужого процесса

Сообщение Vova_2581 » 11.02.2023 (Сб) 11:06

The trick писал(а):Получается что без ручного маршалинга ты не вызовешь и придется выделять память в чужом процессе, либо мапить ее.

Да вот и я о том же... ((
Хакер Ок. посмотрю...

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как получить список ListView чужого процесса

Сообщение Vova_2581 » 12.02.2023 (Вс) 18:18

Ну... кое-что получается, воздержусь пока от комментариев, просто боюсь спугнуть удачу. :wink:
Мне неожиданно помог сам GDK, причем он сам об этом ничего не знает.
В общем, попробую "причесать" то, что получилось, и когда все будет готово выложу весь листинг сюда.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как получить список ListView чужого процесса

Сообщение Vova_2581 » 13.02.2023 (Пн) 22:33

Получилось!! Ура!! :alien:
Через пару дней все выложу сюда с комментариями. Сейчас нет времени писать, нужно отлучится по работе. Если в двух словах... как аннотация... перемешал коды из двух разных форумов, причем, как VB так и С++ потом скомпилировал в рабочий код. Все проверил. Работает 100%!!! Капец! :D

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как получить список ListView чужого процесса

Сообщение Vova_2581 » 18.02.2023 (Сб) 14:50

Итак, продолжим...
Анализируя свой код я заметил, что не указал значение константы LVIF_TEXT.
Решил погуглить... и случайно вышел на соседний форум по адресу -->
http://www.vbnet.ru/forum/show.aspx?id=184931
в котором нашел листинг кода от GDK автор не выложил листинг здесь, но выложил его туда. Когда я его просмотрел то был в шоке! Капец! Этот то, что надо! Там оно в виде функции, я его немного переделал, так, чтобы иметь возможность получить элементы всего списка в одной процедуре сразу и не делать каждый раз выделение памяти VirtualAllocEx для каждого отдельного элемента списка в чужом процессе. Думаю так будет корректно, тем более, что я взял для примера листинг на С++ о котором писал вначале топика вот здесь -->
https://www.codeproject.com/Articles/5570/Stealing-Program-s-Memory
В общем, объединил это все вместе и получил отличный результат.
Все работает!!!
Для примера сделал отдельный проект с ListView и своей переделанной программой прочел все его элементы.
Я не знаю, прочтет это ли нет автор кода с никнэймом GDK, но я хочу выразить ему ОГРОМНУЮ(!) благодарность за его труд и пример на форуме. GDK, СПАСИБО ВАМ БОЛЬШОЕ!!! Вы меня спасли! Теперь я могу работать дальше. СПАСИБО!!!
Все проекты, как и обещал, выкладываю здесь...
Вложения
Read ListView another program.rar
Примеры с комментариями...
(14.82 Кб) Скачиваний: 27

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как получить список ListView чужого процесса

Сообщение Vova_2581 » 18.02.2023 (Сб) 14:56

P.S. Для новичков... если что-то не будет получатся в чтении именно вашего ListView, попробуйте изменить значение .iSubItem структуры lvi на 1 или 2. Или же таким образом получать другие подэлементы списка. В общем, пробуйте.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 12

    TopList