監視 Process Monitor 的事件
今天因為工作的需要,研究了一下怎麼從 Process Monitor 裡面,
取出其中的事件做分析~
因為有原始碼的關係,這看起來並沒有想像中的困難,
但是裡面用到了幾個平常不常用的 API,挺有趣的…
就想把這些部分記錄一下~~
首先第一步,是先找到 Process Monitor 的視窗。
下面的程式會一直迴圈等到視窗開啟~
HWND hwndProcMon = FindWindow("PROCMON_WINDOW_CLASS", NULL);
while (hwndProcMon == NULL)
{
Sleep(250);
hwndProcMon = FindWindow("PROCMON_WINDOW_CLASS", NULL);
}
接下來,找到其中的 list view 視窗。這就是我們要監視的視窗。
HWND hwndListView = FindWindowEx(hwndProcMon, NULL, "SysListView32", NULL);
接下來的才是重點~
平常我們可以直接送 LVM_GETITEMTEXT 這個訊息給 list view,取得裡面的內容,
問題是同時必須提供一塊記憶體來儲存取得的內容。
因為我們的程式不是 Process Monitor,因此我們自己的記憶體傳給 list view 是沒有用的。
因此就會用到了 VirtualAllocEx(), WriteProcessMemory(), ReadProcessMemory() 這些我沒用過的 API 了~
LVITEM* plvItemRemote = (LVITEM*)VirtualAllocEx(hProcessProcMon, NULL,
sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
char* plvTextRemote = (char*)VirtualAllocEx(hProcessProcMon, NULL,
PROC_MON_LIST_VIEW_BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
上面兩行就是在 Process Monitor 的位址空間中,
取得兩塊記憶體,分別給 LVITEM 和 LVITEM 中的文字用。
接下來,我們準備好一個 LVITEM 的結構,
注意裡面的 pszText 要指向我們在 Process Monitor 中取得的記憶體空間:
LVITEM lvItemLocal = {0};
lvItemLocal.cchTextMax = PROC_MON_LIST_VIEW_BUFFER_SIZE;
lvItemLocal.iSubItem = 0;
lvItemLocal.pszText = plvTextRemote;
上面的程式指定了我們要取得第 0 column 的值。
接著,就可以把這個 LVITEM 結構複製到 Process Monitor 中的記憶體,
就好像 Process Monitor 自已建立了這個 LVITEM 結構一樣:
WriteProcessMemory(hProcessProcMon, plvItemRemote,
&lvItemLocal, sizeof(lvItemLocal), NULL);
送出 LVM_GETITEMTEXT 訊息給 list view,好取得其中的內容。
當然,這個內容會被儲存到 Process Montior 裡面那塊我們事先準備好的記憶體。
這裡的 nItemChecked 是指第幾個 event。
SendMessage(hwndListView, LVM_GETITEMTEXT,
(WPARAM)nItemChecked, (LPARAM)plvItemRemote);
最後,我們再從那塊記憶體中讀出內容,就達到目的了~~
char szTextLocal[PROC_MON_LIST_VIEW_BUFFER_SIZE] = {0};
ReadProcessMemory(hProcessProcMon, plvTextRemote,
szTextLocal, sizeof(szTextLocal), NULL);
這裡是完整的程式,執行的話就可以從 Process Monitor 中,
截取出事件並印出來囉~~