• 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;
    }

  • 相关阅读:
    深入理解计算机系统(3.7)------过程(函数的调用原理)
    深入理解计算机系统(3.6)------汇编的流程控制
    深入理解计算机系统(3.5)------特殊的算术操作指令
    深入理解计算机系统(3.4)------算术和逻辑操作
    深入理解计算机系统(3.3)------操作数指示符和数据传送指令
    深入理解计算机系统(3.2)------程序编码以及数据格式
    redis调优 -- 内存碎片
    windows及linux环境下永久修改pip镜像源的方法
    Nginx限制某个IP同一时间段的访问次数和请求数示例代码
    Pycharm安装详细教程
  • 原文地址:https://www.cnblogs.com/kuangke/p/11133727.html
Copyright © 2020-2023  润新知