转载: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;
}

DuplicateHandle进程间句柄复制的更多相关文章

  1. [转]Windows 下的进程间通讯及数据共享

    http://blog.codingnow.com/2005/10/interprocess_communications.html Windows 下有很多方法实现进程间通讯,比如用 socket, ...

  2. windows 进程间通讯方法

    Windows平台为我们提供了多种进程间通信的机制,主要包括:注册表方式.共享文件方式.共享内存方式.共享数据段.映射文件方式.管道方式. 剪贴板方式.消息方式.其中注册表方式需要增加注册表表项,而注 ...

  3. 输入系统:进程间双向通信(socketpair+binder)

    一.双向通信(socketpair) socketpair()函数用于创建一对无名的.相互连接的套接子,如果函数成功,则返回0,创建好的套接字分别是sv[0]和sv[1]:否则返回-1,错误码保存于e ...

  4. Windows进程间的通信

    一.进程与进程通信   进程间通信(Interprocess Communication, IPC)是指不同的进程之间进行数据共享和数据交换. 二.进程间通信方式 1.  文件映射 注:文件映射是在多 ...

  5. 使用 WM_COPYDATA 在进程间共享数据

    开发中有时需要进程间传递数据,比如对于只允许单实例运行的程序,当已有实例运行时,再次打开程序,可能需要向当前运行的实例传递信息进行特殊处理.对于传递少量数据的情况,最简单的就是用SendMessage ...

  6. Windows进程间各种通信方式浅谈

    1 Windows进程间通信的各种方法 进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码.数据以及它可利用的系统资源(如文件.管道等)组成. 多进程/多线程是Windows操作系 ...

  7. 一个进程间同步和通讯的 C# 框架

    转自原文 一个进程间同步和通讯的 C# 框架 threadmsg_demo.zip ~ 41KB    下载 threadmsg_src.zip ~ 65KB    下载 0.背景简介 微软在 .NE ...

  8. c++ 网络编程(三) LINUX/windows 进程间的通信原理与实现代码 基于多进程的服务端实现

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9613027.html 锲子:进程与线程是什么,他们的区别在哪里: 1 进程概念 进程是程序的一 ...

  9. C#进程间通讯或同步的框架引荐

    这篇文章主要介绍了一个进程间通讯同步的C#框架,代码具有相当的稳定性和可维护性,随着.NET的开源也会被注入更多活力,推荐!需要的朋友可以参考下  0.背景简介 微软在 .NET 框架中提供了多种实用 ...

随机推荐

  1. Locust性能模块浅谈

    今天接触到Locust性能模块,下面介绍一下安装与简单的应用 1.安装方式:pip install Locust Locust支持Python 2.7, 3.4, 3.5, and 3.6的版本,小编 ...

  2. javascript数据结构与算法——栈

    前言: 栈就是和列表类似的一种数据结构,不过栈的特点是'后人先出'.栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样操作很快,而且容易实现. 1. 栈的介绍: 栈是一种特殊的列表,栈内的 ...

  3. jetbreains的crack方法

    https://zhile.io/2018/08/20/jetbrains-license-server-crack.html

  4. Cisco网络模拟器踩坑记录

    1.在我们新建一个拓扑图的时候,选择设备之间的连线种类有时会导致线路不通的情况(两个端口上为红色点)这时候建议拆除这条线后选择闪电标记 的万能线帮助我们自动创建连线(这时就能根据它显示的线条种类得知应 ...

  5. 2019年牛客多校第一场 C题Euclidean Distance 暴力+数学

    题目链接 传送门 题意 给你\(n\)个数\(a_i\),要你在满足下面条件下使得\(\sum\limits_{i=1}^{n}(a_i-p_i)^2\)最小(题目给的\(m\)只是为了将\(a_i\ ...

  6. 51nod 2500 后面第一个大于

    小b有一个长度为n的序列t,现在她对于每个i,求最小的正数j满足i+j≤ni+j≤n且ti+j>titi+j>ti,输出j,如果不存在这样的j,则输出0. 样例解释: 对于i=1,t2&g ...

  7. js里调用函数时,函数名带括号与不带括号的区别

    function test(){ return 1;}var a=test;console.log(a);//输出[Function: test]var b=test();console.log(b) ...

  8. 4、markdown基本语法

    一.前言 由于有些语法无法在博客园展示,推荐使用Typora解锁全套,下载地址:https://www.typora.io/ 推荐使用jupyter,使用方法:https://www.cnblogs. ...

  9. 深入理解JVM内存分配和常量池

    一.虚拟机的构成 虚拟结主要由运行时数据区.执行引擎.类加载器三者构成: 而我们所说的JVM内存模型指的就是运行时数据区,下面具体分析一下运行时数据区: 二.运行时数据区组成和各个区域的作用 我们看到 ...

  10. super()函数

    1.简单的使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: 在上面,A ...