在windows下,不管是進程還是句柄或者文件,他們都可以抽象為一個HANDLE,如果有接觸過linux編程的都知道,linux下一切皆文件,對進程,文件,socket的操作都是通過int來標識的,windows下的HANDLE概念也跟linux下的int概念差不多,都可以歸結為類似與ID的數據類型,只是表示形式不一樣,我們對於所有對象的操作都需要通過這個標識來傳遞
當然在WINDOWS下還包括HICON,HWND等,大部分都是UI相關的,我們值需要知道HWND是操作窗口的標識符,HICON是圖標的標識符,我們后面將會講到如何通過窗口來操作其他進程
如果我們要操作其他的進程,首先需要的肯定是要能夠在自己的程序中拿到其他進程的標識符,在windows下為我們提供了OpenProcess這個函數
HANDLE OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId)
dwDesireAccess是操作權限,在本章節中設置為PROCESS_ALL_ACCESS
bInheritHandle,表示所得到的進程句柄是否可以被繼承
dwProcessID,這個是最重要的,就是進程的ID
我們只要能想辦法拿到進程的ID就可以對該進程進行操作了,那么我們怎么拿到進程的ID呢??
1.通過任務管理器
我們打開任務管理器,點擊菜單欄的查看->選擇列->把PID打上勾,然后我們返回任務管理器,有一行PID,就是我們需要的進程的ID了
這個時候我們只要通過這個數值就可以調用OpenProcess來獲取該進程的句柄了
HANDLE OpenProcessByID(const DWORD id) { return OpenProcess(PROCESS_ALL_ACCESS,FALSE,id); }
2.通過HWND,即窗口
WINDOWS提供了一個API來讓我們找到一個進程的窗口句柄,即FindWindows,同時,我們可以通過GetWindowThreadProcessID,我們只要傳入通過FindWindow找到的HWND,然后傳給GetWindowThreadProcessID就可以找到該進程的ID
HANDLE OpenProcessByWindowName(const char *name) { HWND hWnd = FindWindow(NULL,name); if (hWnd != NULL) { DWORD ThreadID = -1; DWORD ProcessID = -1; ThreadID = GetWindowThreadProcessId(hWnd,&ProcessID); return OpenProcessByID(ProcessID); } return INVALID_HANDLE_VALUE; }
3.查找進程名稱
在Windows下,我們可以通過枚舉系統所有進程的名稱,然后根據進程的名稱一個個地去比較來找到對應的進程ID
HANDLE OpenProcessByProcessNmae(const char *name) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if (hSnapshot == INVALID_HANDLE_VALUE) { CloseHandle(hSnapshot); return INVALID_HANDLE_VALUE; } PROCESSENTRY32 pe32; DWORD id = 0; pe32.dwSize = sizeof(PROCESSENTRY32); if ( !Process32First(hSnapshot,&pe32) ) { CloseHandle(hSnapshot); return INVALID_HANDLE_VALUE; } while ( 1 ) { pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32Next(hSnapshot,&pe32) == FALSE) break; if ( strcmp(pe32.szExeFile,name)==0 ) { return OpenProcessByID(pe32.th32ProcessID); } } CloseHandle(hSnapshot); return INVALID_HANDLE_VALUE; }
我們拿到進程的句柄以后,我們就可以干我們接下來的事情了,比如代碼注入,比如偷取數據之類的