標籤:bin begin 共用 snap ntp eof int ssh round
在進程之間共用核心物件控點的一種方法:DuplicateHandle
簡單地說,該函數取得某個進程控制代碼表中的一個表項,然後把它拷貝到另一個進程的控制代碼表中。
BOOL WINAPI DuplicateHandle( __in HANDLE hSourceProcessHandle, __in HANDLE hSourceHandle, __in HANDLE hTargetProcessHandle, __out LPHANDLE lpTargetHandle, __in DWORD dwDesiredAccess, __in BOOL bInheritHandle, __in DWORD dwOptions );
hSourceProcessHandle:源進程核心控制代碼(即負責傳遞核心物件控點的進程控制代碼)
hSourceHandle:要傳遞的核心物件控點
hTargetProcessHandle:目標進程核心控制代碼
lpTargetHandle:接收核心物件控點的地址(先隨便聲明一個HANDLE)
dwDesiredAccess:TargetHandle控制代碼使用何種存取遮罩(這個掩碼是在控制代碼表中的一項)
bInheritHandle:是否擁有繼承
dwOptions:當設DUPLICATE_SAME_ACCESS時,表示於源的核心對象所有標誌一樣,此時wDesiredAccess可標誌為0 當設DUPLICATE_CLOSE_SOURCE時,傳輸完後,關閉源中的核心物件控點
此函數能否成功調用還要看你是否有足夠的許可權去操作目標進程
通常目標進程的核心控制代碼是利用OpenProcess()得到的
注意:不要試圖在源進程中利用CloseHandle()關閉TargetHandle,因為這個TargetHandle控制代碼值並不屬於源進程的控制代碼表中的,若錯誤關閉了,會產生不可預料的結果!
不知道為何要用複製控制代碼函數,我利用處理序間通訊把控制代碼傳給目標進程不就行了嗎?
這樣的想法就大錯特錯了,我們表面上是在複製控制代碼值,實際上是把該控制代碼在源進程控制代碼表中的所有項複製到目標進程的控制代碼表中,而且使該核心對象的計數器+1了,如果只是簡單的只傳控制代碼值,目標進程的控制代碼表中是不會有所增加的。
下面例子示範在ApiDuplicateHandleSource.exe中建立一個線程,將該線程控制代碼複製到ApiDuplicateHandle.exe中去,在進程ApiDuplicateHandle.exe中結束該線程。
// ApiDuplicateHandleSource.cpp
#include <iostream>#include <Windows.h>#include <process.h>#include <tchar.h>#include <TlHelp32.h>using namespace std;unsigned __stdcall thread (void * lpPragma);HANDLE GetProcessHandle(LPCTSTR szName);int main (void){ HANDLE hThread = NULL; hThread = (HANDLE)_beginthreadex(NULL, 0, thread, NULL, 0, NULL); cout << "My thread handle is " << hThread << endl; HANDLE hTarget = NULL; BOOL bSucc = FALSE; //你是不是想說這裡的hThread與調用DuplicateHandle相關? bSucc = DuplicateHandle (GetCurrentProcess(), //當前進程的源進程控制代碼 hThread, //當前進程中存在的線程資源控制代碼(核心對象) GetProcessHandle(_T("ApiDuplicateHandle.exe")), //目標進程的控制代碼 &hTarget, //要得到的目的控制代碼(Out) 0, //訪問的方式 FALSE, //得到的控制代碼能不能被得到的其的進程的子進程繼承 DUPLICATE_SAME_ACCESS ); //訪問選項 if (bSucc) { cout << "控制代碼複製成功, 其控制代碼值為:" << hTarget << endl; } cin.get(); return 0;}unsigned __stdcall thread (void * lpPragma){ while (1) { Sleep (1000); cout << "Please terminal me!" << endl; } return 0;}HANDLE GetProcessHandle(LPCTSTR szName){ HANDLE hSanpshot = NULL; hSanpshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if ( INVALID_HANDLE_VALUE == hSanpshot ) { return NULL; } PROCESSENTRY32 pe; BOOL bOk = FALSE; pe.dwSize = sizeof(pe); bOk = Process32First (hSanpshot, &pe); if (!bOk) return NULL; do { if ( !_tcscmp (pe.szExeFile, szName) ) { return OpenProcess (PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID); } bOk = Process32Next (hSanpshot, &pe); } while (bOk); return NULL;}
// ApiDuplicateHandle.cpp
#include <iostream>#include <Windows.h>#include <stdlib.h>#include <process.h>using namespace std;int main (void){ HANDLE hRecv = NULL; cout << "請輸入複製過來的控制代碼 : " << endl; cin >> hRecv; TerminateThread(hRecv, 0); cin.get(); return 0;}
參考:
http://www.cnblogs.com/staring-hxs/p/3576927.html
http://blog.sina.com.cn/s/blog_4cfc933d0100rsrv.html
Windows API之DuplicateHandle