2012-10-01 2 views
0

다른 응용 프로그램의 ListView 컨트롤 (대화 상자 내에 있음)에 액세스하려고 시도하고 컨트롤 내에서 데이터를 가져옵니다. 코드가 실행Win32- ListView 가져 오기 다른 응용 프로그램에서 콘텐츠 제어

 HWND hListView32 = hRoot; //HANDLE to the ListView control within the Dialog, having class name - "SysListView32" 
     int cnt = (int) ::SendMessage(hListView32, LVM_GETITEMCOUNT, 0, 0L); //returns CORRECT item count of the ListView Control 
     int nItem=0,nRes; 

     for(int nItem=0;nItem<cnt;nItem++) 
     { 
      LVITEM LvItem; // ListView Item struct 
       char Text[255]={0}; 
       char Temp[255]={0}; 
       char Temp1[255]={0}; 

       memset(&LvItem,0,sizeof(LvItem)); 
      LvItem.mask=LVIF_TEXT; 
       LvItem.iSubItem=1; //Trying to get the 2nd Colomn text 

       LvItem.pszText=Text; //Does not returns any Text, after the below SendMessage is executed??? 

       LvItem.cchTextMax=256; 
       LvItem.iItem=nItem; 
       nRes = (int)::SendMessage(hListView32,LVM_GETITEMTEXT, nItem, (LPARAM)&LvItem); 
       DWORD dd = ::GetLastError(); //returns 0 
     } 

하지만, 내가 컨트롤 내에서 데이터를 받고 있지 않다 : 여기에 내가 쓰고 있어요 (appropiate 의견)는 Win32 코드입니다. 그러나 컨트롤 내에서 올바른 항목 수를 검색 할 수 있지만 데이터가 없습니다.

또 다른 방법은 MSAA 후크를 사용하여 데이터를 가져 오는 것입니다. 그러나 그것은 매우 길고 성가신 과정 일 것입니다. 여기서 아이디어가 부족합니다. Pls 도움.

감사합니다.

+0

'LVM_GETITEMTEXT'는 동일한 프로세스 내에서만 작동합니다. 예 : 데이비드 Heffernans 댓글 [이 질문에] (http://stackoverflow.com/questions/4857411/listview-getitem-macro-lv-getitemtext-returns-empty-string-while-getting-ano). – user786653

답변

1

몇 가지 가능성이 있습니다.

  1. DLL Injection Windows 후크 사용. 장점 : 간단하고 똑바로. 단점 : 많은 프로세스가이 DLL을로드합니다.

  2. DLL Injection 결정 과정은 WriteProcessMemory으로 메모리의 글이 프로세스의 컨텍스트에서 VallocEx을 이용하여 가상 메모리 chunc 할당, 디버깅을 개방하고 LoadLibrary 함수의 시작 주소와 원격 스레드를 생성하여 라이브러리를로드한다. 장점 : 단일 프로세스가 영향을받습니다. 단점 : 후크 솔루션보다 조금 복잡합니다.

  3. 프로세스 메모리 읽기. 옵션 2와 동일하지만이 메모리를 작성하고 원격으로 코드를 실행하는 대신 유효한 창에서 올바른 메모리 위치를 제공하는 메시지에 LVM_GETITEMTEXT 메시지를 보낸 다음 ReadProcessMemory으로 해당 위치를 읽습니다.

+0

DLL 주입은 * 유일한 * 접근법이 아닙니다. 또한 대상 응용 프로그램에서 메모리를 할당하고'LVM_GETITEMTEXT' 메시지를 처리하도록 할 수 있습니다. – user786653

+0

네, 맞습니다. – Serge

+0

@ user786653하지만 지금까지 당신은 dll을로드하는 한 단계 - 메모리를 할당하고 읽기위한 프로세스를 열었습니다. – Serge

1

ListView를 소유하고있는 프로세스의 주소 공간 내에서만 작동하는 ListView 메시지가 작동합니다. 동일한 프로세스 내에서 메모리 블록을 할당하려면 VirtualAllocEx()을 사용해야합니다. 그런 다음 WriteProcessMemory()으로 쓰고 ListView에 필요에 따라 채우면 ReadProcessMemory()으로 읽을 수 있고 VirtualFreeEx()으로 할당 해제 할 수 있습니다.

이 (간결함을 위해 생략 오류 처리) 시도 : 나는 레미 Lebeau에 의해 코드를 copypasted

HWND hListView32 = hRoot; 

int cnt = (int) ::SendMessage(hListView32, LVM_GETITEMCOUNT, 0, 0); 
if (cnt > 0) 
{ 
    DWORD dwProcessId; 
    GetWindowThreadProcessId(hListView32, &dwProcessId); 

    HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, dwProcessId); 

    LVITEM *pLvItem = (LVITEM*) VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE); 
    LPTSTR pText = (LPTSTR) VirtualAllocEx(hProcess, NULL, sizeof(TCHAR)*256, MEM_COMMIT, PAGE_READWRITE); 

    for(int nItem = 0; nItem < cnt; ++nItem) 
    { 
     TCHAR Text[256] = {0}; 

     LVITEM LvItem = {0}; 
     LvItem.mask = LVIF_TEXT; 
     LvItem.iSubItem = 1; 
     LvItem.pszText = pText; 
     LvItem.cchTextMax = 256; 
     LvItem.iItem = nItem; 

     WriteProcessMemory(hProcess, pLvItem, &LvItem, sizeof(LVITEM), NULL); 

     int nRes = (int) ::SendMessage(hListView32, LVM_GETITEMTEXT, nItem, (LPARAM)pLvItem); 
     if (nRes > 0) 
      ReadProcessMemory(hProcess, pText, &Text[0], sizeof(TCHAR)*nRes, NULL); 

     // use Text as needed... 
    } 

    VirtualFreeEx(hProcess, pText, 0, MEM_RELEASE); 
    VirtualFreeEx(hProcess, pLvItem, 0, MEM_RELEASE); 
    CloseHandle(hProcess); 
} 
0

을하지만, 내 특정 경우에 아주 이상한 노력하고 있습니다. 요소 수는 SendMessage (listview, LVM_GETITEMCOUNT, 0, 0) 을 통해 올바르게 수집되지만주기마다 매번 같은 요소가 반복됩니다! 처음이나 마지막 요소가 아니고 선택 요소가 아니라 무작위 인 것처럼 보입니다. 다음은 내 코드입니다 :

HWND win=FindWindowEx(NULL, NULL, _("TEventLogView"), NULL); 
HWND listview=FindWindowEx(win, NULL, _("TListView"), NULL); 
int cnt = (int) ::SendMessage(listview, LVM_GETITEMCOUNT, 0, 0); 
if (cnt > 0) 
{ 
    DWORD dwProcessId; 
    GetWindowThreadProcessId(listview, &dwProcessId); 
    int n = grdEvents->GetNumberRows(); 
    HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, dwProcessId); 
    LVITEM *pLvItem = (LVITEM*) VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE); 
    LPTSTR pText = (LPTSTR) VirtualAllocEx(hProcess, NULL, sizeof(TCHAR)*255, MEM_COMMIT, PAGE_READWRITE); 
    for(int nItem = 0; nItem < cnt; ++nItem) 
    { 
     // need to read 1 - 3 subitems 
     for (int j = 1; j < 4; j++) 
     { 
     TCHAR Text[255] = {0}; 
     LVITEM LvItem = {0}; 
     LvItem.mask = LVIF_STATE | LVIF_TEXT; 
     LvItem.pszText = pText; 
     LvItem.cchTextMax = sizeof(TCHAR)*255; 
     LvItem.iItem = nItem; 
     LvItem.iSubItem = j; 
     int nRes1 = WriteProcessMemory(hProcess, pLvItem, &LvItem, sizeof(LVITEM), NULL); 
     int nRes2 = (int) ::SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)pLvItem); 
     if (nRes2 > 0) 
     { 
      ReadProcessMemory(hProcess, pText, &Text[0], sizeof(TCHAR)*nRes2, NULL); 
      // insert into wxWidgets grid 
      grdEvents->SetCellValue(nItem, j - 1, Text); 
     } 
     } 
     VirtualFreeEx(hProcess, pText, 0, MEM_RELEASE); 
     VirtualFreeEx(hProcess, pLvItem, 0, MEM_RELEASE); 
     CloseHandle(hProcess); 
    } 
} 
관련 문제