本示範展示如何透過進程注入技術,讀取目標視窗(如「SYS (C:)」)中 SysListView32 控制項的列表項目內容。程式碼精簡,專注於核心流程:尋找視窗 → 列舉子控制項 → 開啟進程 → 跨進程記憶體分配與讀寫 → 發送 LVM_GETITEMTEXT 取得文字。
FindWindow / FindWindowEx:定位目標視窗與 ListView 控制項句柄。EnumChildWindows:回呼函式中識別 SysListView32 類別,取得 g_hListCtrl。GetWindowThreadProcessId + OpenProcess(PROCESS_ALL_ACCESS):取得目標進程控制代碼。VirtualAllocEx:在目標進程配置記憶體,存放 LVITEM 結構與文字緩衝區。WriteProcessMemory:寫入初始化的 LVITEM(指定 cchTextMax、pszText 指向遠端緩衝區)。SendMessage(LVM_GETITEMTEXT):觸發目標進程填充文字到遠端緩衝區。ReadProcessMemory:讀回本地緩衝區,顯示於介面。VirtualFreeEx / CloseHandle:釋放遠端記憶體與關閉句柄。HWND hWnd = ::FindWindow(NULL, _T("SYS (C:)"));
EnumChildWindows(hWnd, EnumFunc, 0); // 回呼中設定 g_hListCtrl
DWORD pid; GetWindowThreadProcessId(g_hListCtrl, &pid);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LVITEM* pLvi = (LVITEM*)VirtualAllocEx(hProc, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
TCHAR* pBuf = (TCHAR*)VirtualAllocEx(hProc, NULL, 512 * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
LVITEM lvi = {0}; lvi.cchTextMax = 512; lvi.iSubItem = 0; lvi.pszText = (LPTSTR)pBuf;
WriteProcessMemory(hProc, pLvi, &lvi, sizeof(LVITEM), NULL);
for (int i = 0; i < g_iRecords; ++i) {
::SendMessage(g_hListCtrl, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pLvi);
TCHAR localBuf[512];
ReadProcessMemory(hProc, pBuf, localBuf, 512 * sizeof(TCHAR), NULL);
m_Edt_str += localBuf; m_Edt_str += _T("\r\n");
Sleep(100);
}
VirtualFreeEx(hProc, pLvi, 0, MEM_RELEASE);
VirtualFreeEx(hProc, pBuf, 0, MEM_RELEASE);
CloseHandle(hProc);
PROCESS_ALL_ACCESS(Vista+ 需 UAC 提權或簽名)。SetWindowsHookEx)、DLL 注入、遠端執行緒建立(CreateRemoteThread)等進階主題。測試環境: Windows XP(文中原環境),現代 Windows 需考慮安全機制(ASLR、DEP、UIPI、CFG)對注入的限制。