Jump to content


Photo

Cotilleando un ListView de otro proceso...


  • Please log in to reply
3 replies to this topic

#1 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4111 posts
  • LocationMadrid - España

Posted 25 June 2015 - 06:33 AM

Leyendo detenidamente la pregunta de look vi un detalle que pretendía que no está contamplado en WinInfo. Se trata de poder leer el contenido de un ListView.

Para esa tarea, Windows tiene previsto el acceso a través de mensajes encapsulados en macros estilo C: List View, la pega es que no funcionan si se trata de acceder desde un proceso distinto, se debe a la compartimentación de la memoria aislada entre procesos. Pudiera parecer que es un escollo insalvable, pero no lo es si "invadimos" el proceso a espiar, para eso están las APIs VirtualAllocEx, WriteProcessMemory y ReadProcessMemory.

Armados con estas APIs y obteniendo el Handle del proceso anfitrión podemos invadir su memoria y extraer los datos que buscamos.

Lo que sigue es un ejemplo que fisgonea en un ListView de un proceso ajeno coniciendo previamente el Handle de ventana de dicho control y las coordenadas del "mouse" donde se encuentra el Item a asaltar, obtenemos los subitems. El sumitem[0] representa el texto principal del Item mientras que números superiores representan los siguientes subitems en orden.

El código está diseñado para encajarlo en WinInfo, que ya se encarga de obtener el Handle y las coordenadas necesarias pero se puede adaptar para uso en otros entronos.
 

delphi
  1. function GetLVText(hListView: HWND; X, Y: integer; iSubItem: Cardinal): String;
  2. var
  3. pid: DWORD;
  4. hProcess: THANDLE;
  5. IInfo: TLVHITTESTINFO;
  6. _IInfo: PLVHITTESTINFO;
  7. Index: integer;
  8. Buffer: array [0..511] of CHAR;
  9. _Buffer: PCHAR;
  10. Item: TLVITEM;
  11. _Item: PLVITEM;
  12. begin
  13. Result:= '';
  14. GetWindowThreadProcessId(hListView, pid);
  15. hProcess:= OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
  16. PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION, FALSE, pid);
  17. if hProcess <> THANDLE(0) then
  18. begin
  19. // Encontramos el índice del LVItem en X, Y
  20. Index:= -1;
  21. IInfo.pt:= Point(10, Y);
  22. _IInfo:= VirtualAllocEx(hProcess, nil, sizeof(TLVHITTESTINFO), MEM_COMMIT, PAGE_READWRITE);
  23. WriteProcessMemory(hProcess, _IInfo, @IInfo, sizeof(TLVHITTESTINFO), PDWORD(0)^);
  24. Index:= ListView_HitTest(hListView, _IInfo^);
  25. if Index >= 0 then
  26. begin
  27. // Encontramos el Texto del Item
  28. _Buffer:= VirtualAllocEx(hProcess, nil, sizeof(Buffer), MEM_COMMIT, PAGE_READWRITE);
  29. _Item:= VirtualAllocEx(hProcess, nil, sizeof(TLVITEM), MEM_COMMIT, PAGE_READWRITE);
  30.  
  31. Item.iSubItem:= iSubItem;
  32. Item.pszText:= _Buffer;
  33. Item.cchTextMax:= sizeof(Buffer);
  34.  
  35. WriteProcessMemory(hProcess, _Item, @Item, sizeof(TLVITEM), PDWORD(0)^);
  36. SendMessage(hListView, LVM_GETITEMTEXT, Index, Cardinal(_Item));
  37. ReadProcessMemory(hProcess, _Buffer, @Buffer[0], sizeof(Buffer), PDWORD(0)^);
  38. Result:= String(Buffer);
  39. // Liberamos memoria del proceso
  40. VirtualFreeEx(hProcess, _Item, 0, MEM_RELEASE);
  41. VirtualFreeEx(hProcess, _Buffer, 0, MEM_RELEASE);
  42. end;
  43. // Liberamos memoria del proceso
  44. VirtualFreeEx(hProcess, _IInfo, 0, MEM_RELEASE);
  45. end;
  46. end;


Saludos.
  • 5

#2 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4111 posts
  • LocationMadrid - España

Posted 25 June 2015 - 07:41 AM

Para los que les apetezca el C/C++, esta es la versión para BCB:
 


cpp
  1. String GetLVText(HWND hListView, int X, int Y, int iSubItem)
  2. {
  3. String Text = "";
  4. DWORD pid;
  5. GetWindowThreadProcessId(hListView, &pid);
  6. HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|
  7. PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);
  8. if(hProcess){
  9. // Encontramos el índice del LVItem en X, Y
  10. LVHITTESTINFO IInfo, *_IInfo;
  11. int Index = -1;
  12. IInfo.pt = TPoint(10, Y);
  13. _IInfo = (LVHITTESTINFO*)VirtualAllocEx(hProcess, NULL, sizeof(LVHITTESTINFO), MEM_COMMIT, PAGE_READWRITE);
  14. WriteProcessMemory(hProcess, _IInfo, &IInfo, sizeof(LVHITTESTINFO), NULL);
  15. Index = ListView_HitTest(hListView, _IInfo);
  16. if(Index>=0){
  17. // Encontramos el Texto del Item
  18. char Buffer[512];
  19. LVITEM Item, *_Item;
  20.  
  21. char *_Buffer = (char*)VirtualAllocEx(hProcess, NULL, sizeof(Buffer), MEM_COMMIT, PAGE_READWRITE);
  22. _Item = (LVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
  23.  
  24. Item.iSubItem = iSubItem;
  25. Item.pszText = _Buffer;
  26. Item.cchTextMax = sizeof(Buffer);
  27.  
  28. WriteProcessMemory(hProcess, _Item, &Item, sizeof(LVITEM), NULL);
  29. int n = SendMessage(hListView, LVM_GETITEMTEXT, Index, (LPARAM)_Item);
  30. ReadProcessMemory(hProcess, _Buffer, Buffer, sizeof(Buffer), NULL);
  31. Text = String(Buffer);
  32. // Liberamos memoria del proceso
  33. VirtualFreeEx(hProcess, _Item, 0, MEM_RELEASE);
  34. VirtualFreeEx(hProcess, _Buffer, 0, MEM_RELEASE);
  35. }
  36. // Liberamos memoria del proceso
  37. VirtualFreeEx(hProcess, _IInfo, 0, MEM_RELEASE);
  38. }
  39. return Text;
  40. }

Saludos.


  • 2

#3 ELKurgan

ELKurgan

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 566 posts
  • LocationEspaña

Posted 25 June 2015 - 11:38 PM

Como siempre, me descubro ante tu sabiduría.

 

¡Impresionante!

 

Saludos


  • 0

#4 sir.dev.a.lot

sir.dev.a.lot

    Advanced Member

  • Miembros
  • PipPipPip
  • 545 posts
  • Location127.0.0.1

Posted 13 July 2016 - 07:20 PM

Delphi version NOSTALGIA!   :)

:)


  • 0




IP.Board spam blocked by CleanTalk.