DuplicateHandle进程间句柄复制

1、

BOOL DuplicateHandle(
  HANDLE hSourceProcessHandle,
  HANDLE hSourceHandle,
  HANDLE hTargetProcessHandle,
  LPHANDLE lpTargetHandle,
  DWORD dwDesiredAccess,
  BOOL bInheritHandle,
  DWORD dwOptions
);

作用:这个函数将一个进程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、通过进程名称获取进程句柄:

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

参数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;
}



  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 C++ 中,可以使用 Windows API 函数来实现遍历进程、查找指定进程、查找指定句柄、关闭指定句柄的功能。示例代码如下: ```c++ #include <windows.h> #include <iostream> #include <tchar.h> BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { DWORD processId; GetWindowThreadProcessId(hwnd, &processId); if (processId == *((DWORD*)lParam)) { // 找到了指定进程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId); if (hProcess == NULL) { std::cout << "OpenProcess failed: " << GetLastError() << std::endl; return FALSE; } // 遍历进程中的句柄,查找指定句柄 HANDLE hHandle = NULL; for (DWORD i = 0; i < 65536; i++) { hHandle = (HANDLE)i; if (DuplicateHandle(hProcess, hHandle, GetCurrentProcess(), &hHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { TCHAR lpFileName[MAX_PATH]; if (GetFinalPathNameByHandle(hHandle, lpFileName, MAX_PATH, VOLUME_NAME_NT)) { if (_tcsstr(lpFileName, _T("\\Device\\HarddiskVolume2\\path\\to\\file")) != NULL) { // 找到了指定句柄,关闭句柄 if (!CloseHandle(hHandle)) { std::cout << "CloseHandle failed: " << GetLastError() << std::endl; } } } CloseHandle(hHandle); } } CloseHandle(hProcess); return FALSE; } return TRUE; } int main() { // 遍历所有窗口,查找指定进程 DWORD processId = 1234; EnumWindows(EnumWindowsProc, (LPARAM)&processId); return 0; } ``` 其中,1234 是要查找的进程 ID,_T("\\Device\\HarddiskVolume2\\path\\to\\file") 是要关闭的句柄对应的文件路径。遍历进程中的句柄可以使用 DuplicateHandle() 函数,获取句柄对应的文件路径可以使用 GetFinalPathNameByHandle() 函数。如果找到了指定句柄,可以使用 CloseHandle() 函数关闭句柄。注意要在关闭句柄之前使用 DuplicateHandle() 函数复制句柄,以避免关闭了错误的句柄

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小米的修行之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值