DuplicateHandle进程间句柄复制

转载:https://blog.csdn.net/u012372584/article/details/78740365

1、

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

作用:这个函数将一个进程A句柄表中的记录项(内核对象)复制到另一个进程B的句柄表中。如果B同时得到了此记录项(内核对象)的句柄值(一般通过进程间通信,A进程将记录项的句柄值传递给B进程),那么在B进程中就可以访问此记录项(内核对象)。

参数1:源进程A内核对象的句柄;
参数3:目标进程B内核对象的句柄;

 

进程句柄的获取:
1、如果进程是当前进程:GetCurrentProcess();
2、如果进程不是当前进程:OpenProcess(__in DWORD dwDesiredAccess,__in BOOL bInheritHandle,__in DWORD dwProcessId);其中dwProcessId可以在任务管理器中获得,或是通过进程间通信获得。
3、通过进程名称获取进程句柄:

  1.  
    HANDLE GetProcessHandle(LPCTSTR szName)
  2.  
    {
  3.  
    HANDLE hSanpshot;
  4.  
    hSanpshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  5.  
    if ( INVALID_HANDLE_VALUE == hSanpshot )
  6.  
    {
  7.  
    return NULL;
  8.  
    }
  9.  
     
  10.  
    PROCESSENTRY32 pe;
  11.  
    BOOL bOk;
  12.  
    pe.dwSize = sizeof(pe);
  13.  
     
  14.  
    bOk = Process32First (hSanpshot, &pe);
  15.  
    if (!bOk)
  16.  
    return NULL;
  17.  
     
  18.  
    do {
  19.  
    if ( !wcscmp (pe.szExeFile, szName) )
  20.  
    {
  21.  
    return OpenProcess (PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
  22.  
    }
  23.  
    bOk = Process32Next (hSanpshot, &pe);
  24.  
    }while (bOk);
  25.  
     
  26.  
    return NULL;
  27.  
    }

参数2:与参数1进程相关的任何类型内核对象的句柄;
参数4:HANDLE变量地址,用来接收复制得到的HANDLE值,可以通过进程间通信,将此值传递到目标进程B,
以用来通知进程B,可以通过此句柄值来访问复制来的内核对象。

 

参数5:TargetHandle句柄使用何种访问掩码(这个掩码是在句柄表中的一项):
      HANDLE_FLAG_INHERIT、HANDLE_FLAG_PROTECT_FROM_CLOSE;
参数6:是否拥有继承;
参数6:当设DUPLICATE_SAME_ACCESS时,表示于源的内核对象所有标志一样,此时wDesiredAccess可标志为0,
       当设DUPLICATE_CLOSE_SOURCE时,传输完后,关闭源中的内核对象句柄。

 

***但很多人都不知道为何要用复制句柄函数,我利用进程间通信把句柄传给目标进程不就行了吗?
这样的想法就大错特错了,我们表面上是在复制句柄值,实际上是把该句柄在源进程句柄表中的所有项复制到目标进程的句柄表中,而且使该内核对象的计数器+1了,如果只是简单的只传句柄值,目标进程的句柄表中是不会有所增加的。

附上一个例子,来源:点击打开链接

将11.exe中的线程句柄复制,通过22.exe输入复制的句柄,结束11.exe中的线程

例子:22.exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <windows.h>
#include <stdlib.h>
#include <process.h>
using namespace std;
 
int main (void)
{
    HANDLE hRecv;
 
    cout << "请输入复制过来的句柄 : "<< endl;
    cin >> hRecv;
 
    TerminateThread(hRecv, 0);
 
    system("pause");
    return 0;
}

例子:11.exe

复制代码
#include <iostream>
#include <windows.h>
#include <process.h>
#include <TlHelp32.h>
using namespace std;

unsigned __stdcall thread (void * lpPragma);
HANDLE GetProcessHandle(LPCTSTR szName);

int main (void)
{
    HANDLE hThread;
    hThread = (HANDLE)_beginthreadex(NULL, 0, thread, NULL, 0, NULL);
    cout << "my thread handle: " << hThread << endl;

    HANDLE hTarget;


    //你是不是想说这里的hThread与调用DuplicateHandle相关?
    if (DuplicateHandle (GetCurrentProcess(), hThread , GetProcessHandle(L"22.exe"), &hTarget, 0, FALSE, DUPLICATE_SAME_ACCESS ) )
        cout << "句柄复制成功, 其句柄值为:" << hTarget << endl;

    cin.get();
    return 0;
}

unsigned __stdcall thread (void * lpPragma)
{
    while (1)
    {
        Sleep (500);
        cout << "terminal me" << endl;
    }

    return 0;
}

HANDLE GetProcessHandle(LPCTSTR szName)
{
    HANDLE hSanpshot;
    hSanpshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if ( INVALID_HANDLE_VALUE == hSanpshot )
    {
        return NULL;
    }

    PROCESSENTRY32 pe;
    BOOL bOk;
    pe.dwSize = sizeof(pe);

    bOk = Process32First (hSanpshot, &pe);
    if (!bOk)
        return NULL;

    do {
        if ( !wcscmp (pe.szExeFile, szName) )
        {
            return OpenProcess (PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
        }
        bOk = Process32Next (hSanpshot, &pe);
    }while (bOk);

    return NULL;
}

原文地址:https://www.cnblogs.com/kuangke/p/11133727.html