进程间共享内核对象是通过句柄复制实现的。

  1. BOOL WINAPI DuplicateHandle(
  2. __in HANDLE hSourceProcessHandle,
  3. __in HANDLE hSourceHandle,
  4. __in HANDLE hTargetProcessHandle,
  5. __out LPHANDLE lpTargetHandle,
  6. __in DWORD dwDesiredAccess,
  7. __in BOOL bInheritHandle,
  8. __in DWORD dwOptions
  9. );

hSourceProcessHandle:源进程的句柄;
hSourceHandle:源内核对象句柄;
hTargetProcessHandle:目标进程的句柄;
lpTargetHandle:指向接收目标内核对象句柄内存的指针;
dwDesiredAccess:访问权限;
bInheritHandle:是否可被继承;
dwOptions:

Value Meaning
DUPLICATE_CLOSE_SOURCE
0x00000001
复制完毕后,将源句柄关闭,无论发生什么错误,源句柄都将被关闭。
DUPLICATE_SAME_ACCESS
0x00000002
忽视dwDesiredAccess参数。复制的句柄具有和源句柄同样的权限。

伪句柄

通过GetCurrentProcess函数,获得的句柄都是伪句柄!伪句柄的值为-1,
其实是一个固定的值!如果你在使用句柄的地方,直接写上-1,那么就代表本进程句柄,
但不建议这么做,也就是说,GetCurrentProcess函数,在目前,总是返回-1

如何获取真实句柄

有两种方法获得真实的进程句柄。

  1. 一种是使用OpenProcess函数,

    1. HANDLE WINAPI OpenProcess(
    2. __in DWORD dwDesiredAccess,
    3. __in BOOL bInheritHandle,
    4. __in DWORD dwProcessId
    5. );

    获得进程内核句柄;
    dwDesiredAccess:希望获得的进程内核对象的句柄,具有什么样的权限。
    bInheritHandle:这个句柄是否可以被继承。
    dwProcessID:要获得进程内核对象句柄的进程ID。
    如果成功,返回句柄,否则返回NULL。
    DWORD WINAPI GetProcessId(
    __in HANDLE Process
    );
    通过进程句柄,获得进程Id;
    Process:进程句柄。

  2. 另外一种是使用DuplicateHandle函数!

  1. BOOL WINAPI DuplicateHandle(
  2. __in HANDLE hSourceProcessHandle,
  3. __in HANDLE hSourceHandle,
  4. __in HANDLE hTargetProcessHandle,
  5. __out LPHANDLE lpTargetHandle,
  6. __in DWORD dwDesiredAccess,
  7. __in BOOL bInheritHandle,
  8. __in DWORD dwOptions
  9. );

复制句柄代码实现

  1. #include<Windows.h>
  2. #include<tchar.h>
  3. int _tmain()
  4. {
  5. HANDLE hProcess=GetCurrentProcess();
  6. //GetCurrentProcess函数,无论在什么情况下,他都返回-1!!!!
  7. //我们把GetCurrentProcess函数返回的句柄,叫伪句柄,当前请情况下,这个伪句柄一定是-1
  8. _tprintf(L"hProcess=%d\n",hProcess);
  9. DWORD sessionid=0;
  10. DWORD processid=0;
  11. processid=GetProcessId((HANDLE)-1);//获取当前进程进程ID
  12. //GetCurrentProcess()获得当前进程句柄!
  13. HANDLE hProcess1=OpenProcess(PROCESS_ALL_ACCESS,FALSE,GetProcessId((HANDLE)-1));
  14. HANDLE hProcess2,hProcess3;
  15. DuplicateHandle((HANDLE)-1,(HANDLE)-1,(HANDLE)-1,&hProcess2,NULL,FALSE,0);
  16. DuplicateHandle((HANDLE)-1,(HANDLE)-1,(HANDLE)-1,&hProcess3,NULL,FALSE,0);
  17. //DuplicateHandle(hProcess, hProcess, hProcess, &hProcess2, NULL, NULL, DUPLICATE_CLOSE_SOURCE);
  18. _tprintf(L"hprocess1=%0x\nhprocess2=%0x\nhProcess3=%0x\n",hProcess1,hProcess2,hProcess3);
  19. CloseHandle(hProcess1);
  20. CloseHandle(hProcess2);
  21. CloseHandle(hProcess3);
  22. _gettchar();
  23. return 0;
  24. }

image.png