首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

跨進程讀取 ListView 控制項內容

     編輯:關於C++

利用 VirtualAllocEx/WriteProcessMemory/ReadProcessMemory 跨進程存取 ListView

由於 ListView 內容儲存在擁有進程的記憶體中,外部進程需在目標進程配置記憶體緩衝區,發送 LVM_GETITEMTEXT 訊息讓目標進程填入緩衝區,再讀回本地。

完整函數 MyGetListViewItem

void MyGetListViewItem(HWND hWindow, TStrings *strlist)
{
    const int nMaxLen = 1023;
    char szBuf[nMaxLen+1];
    int nLVItemCount;
    DWORD dwProcessID;
    HANDLE hProcess;
    LVITEM lvItemLocal;
    DWORD dwBytesRead, dwBytesWrite;
    bool bSuccess, bWriteOK;

    GetWindowThreadProcessId(hWindow, &dwProcessID);
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
    if (!hProcess) return;

    // 在目標進程配置緩衝區
    LPVOID lpTextRemote = VirtualAllocEx(hProcess, NULL, nMaxLen+1, MEM_COMMIT, PAGE_READWRITE);
    LPVOID lpListItemRemote = VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
    if (!lpTextRemote || !lpListItemRemote) return;

    nLVItemCount = ListView_GetItemCount(hWindow);
    strlist->Add("Welcome to www.ccrun.com");
    strlist->Add("ListView的Item總數: " + String(nLVItemCount));
    strlist->Add("---------------------------");

    for (int i = 0; i < nLVItemCount; i++) {
        ZeroMemory(szBuf, nMaxLen+1);
        bWriteOK = WriteProcessMemory(hProcess, lpTextRemote, szBuf, nMaxLen+1, &dwBytesWrite);
        if (!bWriteOK) return;

        lvItemLocal.iItem = i;
        lvItemLocal.iSubItem = 0;
        lvItemLocal.mask = LVIF_TEXT;
        lvItemLocal.cchTextMax = nMaxLen;
        lvItemLocal.pszText = (LPTSTR)lpTextRemote;

        dwBytesWrite = 0;
        bWriteOK = WriteProcessMemory(hProcess, lpListItemRemote, &lvItemLocal, sizeof(LVITEM), &dwBytesWrite);
        if (!bWriteOK) return;

        SendMessage(hWindow, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)lpListItemRemote);

        bSuccess = ReadProcessMemory(hProcess, lpTextRemote, szBuf, nMaxLen+1, &dwBytesRead);
        if (!bSuccess) return;

        strlist->Add(AnsiString(szBuf));
    }

    VirtualFreeEx(hProcess, lpListItemRemote, 0, MEM_RELEASE);
    VirtualFreeEx(hProcess, lpTextRemote, 0, MEM_RELEASE);
    CloseHandle(hProcess);
}

呼叫範例

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // 0x000100DC 為 Spy++ 取得的桌面 ListView 控制代碼 (Win2000)
    MyGetListViewItem((HWND)0x000100DC, Memo1->Lines);
}

注意事項

  • 需 PROCESS_ALL_ACCESS 權限,受限於系統安全策略 (Vista 後需提權)。
  • 僅讀取第一欄 (iSubItem=0);若為 vsReport 模式需額外讀取表頭與子項目。
  • 緩衝區大小 1024 字元足應付一般項目文字。
  • 來源標註:www.ccrun.com, by ccrun(老妖)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved