windwos跨進程使用句柄

windows是通過句柄對進程中的各種內核對象進行引用。實際上windows句柄就是一個索引,索引對應對象的地址,拿到地址就可以獲取對象本身了

句柄表存放的三個值

1句柄是否有繼承權限       2句柄(索引)  3對象的地址

    1                                         1                  0x11111111

 

跨進程使用句柄
  1)子進程繼承父進程句柄的方式
     將父進程的句柄放到子進程的句柄表裏
     1- 句柄本身可以被繼承(有繼承權限),SECURITY_ATTRIBUTES 結構體中的bInheritHandle 成員設置爲TRUE標識句柄可以被繼承
     2- Createprocess的參數bInheritHandles爲TRUE,子進程繼續父進程的句柄,只會拷貝有繼承權限的句柄
     3- 繼承已經打開的句柄,OpenProcess這個API返回的句柄第二個參數爲TRUE,表示指定返回的句柄是否可以由當前進程創建的新進程繼承。 如果爲TRUE,則句柄是可繼承的,相當於第一種把打開的句柄繼承權限改爲1
 

 TCHAR szBuff[] = { _T("創建的子進程名") };
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
 
  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  ZeroMemory(&pi, sizeof(pi));
 
 
  SECURITY_ATTRIBUTES sa;
  sa.nLength = sizeof(sa);
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE; //用CreateProcess創建的進程返回的進程句柄是否可以被繼承(也就是子進程自己的單個句柄),也就是pi.dwProcessId進程句柄是否可以被繼承
 
  if (!CreateProcess(NULL, 
    szBuff, 
    &sa,             // 新建的進程的中的句柄可以被繼承
    NULL,            
    TRUE,            // 是否繼承本進程的句柄 
    0,          
    NULL,    
    NULL,       
    &si,      
    &pi)         
    )
  {
    AfxMessageBox(_T("CreateProcess failed."));
  }

2) 非父子進程使用句柄

    1打開句柄,A進程打開B進程,A進程中的句柄表中添加了一個新句柄,新句柄值不一定相同,但是這個句柄索引的內核對象是同一個


HANDLE OpenProcess(
DWORD dwDesiredAccess, //渴望得到的訪問權限(標誌)
BOOL bInheritHandle, // 是否繼承句柄,指定返回的句柄是否可以由當前進程創建的新進程繼承。 如果爲TRUE,則句柄是可繼承的
DWORD dwProcessId// 進程標示符
);

2複製句柄  -- DuplicateHandle  也是將源進程的句柄傳給目標進程,使得目標進程的句柄表中有源進程的句柄


//1. 查找窗口
HWND hWnd = ::FindWindow(NULL, _T("源進程"));
 
//2. 拿到進程id
DWORD dwProcessId;
::GetWindowThreadProcessId(hWnd, &dwProcessId);
 
//3. 打開進程
HANDLE hProcess = ::OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
dwProcessId);
 
HWND hWndDst = ::FindWindow(NULL, _T("目標進程"));
::GetWindowThreadProcessId(hWndDst, &dwProcessId);
HANDLE hProcessDst = ::OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
dwProcessId);
 
//複製句柄,從當前進程拷貝hProcess句柄給目標進程
HANDLE hTargetHandle;
DuplicateHandle(
GetCurrentProcess(),//源進程的進程句柄,getcurrent獲取的是本進程的句柄
hProcess, //拷貝的句柄
hProcessDst, //目標進程的進程句柄
&hTargetHandle, //給目標進程使用的值
0, //忽略
FALSE, //句柄是否可以被hProcessDst的子進程繼承
DUPLICATE_SAME_ACCESS); //目標進程的句柄和源進程的句柄有相同的權限
 
SetDlgItemInt(EDT_DUPLICATEHANDLE, (UINT)hTargetHandle);

  3) 窗口句柄可以直接跨進程使用

//1. 查找窗口
HWND hWnd = ::FindWindow(NULL, _T("查找的窗口標題"));
 
//2. 拿到進程id
DWORD dwProcessId;
::GetWindowThreadProcessId(hWnd, &dwProcessId);
 
//3. 打開進程
HANDLE hProcess = ::OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
dwProcessId);
 
SetDlgItemInt(EDT_HANDLE, (UINT)hProcess);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章