zoukankan      html  css  js  c++  java
  • 获取真正的进程/线程句柄

    首先在开始正文之前先介绍最简单的获取进程/线程句柄方法。那就是可以在创建进程/线程时获取句柄。

    创建进程/线程是获取句柄。

    //进程创建函数

    BOOL CreateProcess(

    PCTSTR pszApplicationName,

    PTSTR pszCommandLine,

    PSECURITY_ATTRIBUTES psaProcess,

    PSECURITY_ATTRIBUTES psaThread,

    BOOL bInheritHandles,

    DWORD fdwCreate,

    PVOID pvEnvironment,

    PCTSTR pszCurDir,

    PSTARTUPINFO psiStartInfo,

    PPROCESS_INFORMATION ppiProcInfo);

    参数好多啊,如果想了解参数的具体含义可以去查看MSDN,本文不对这些参数进行详解,但是最后一个参数除外,通过它可以获得进程和主线程的内核句柄和ID。先来看一下PPROCESS_INFORMATION结构:

    typedef struct _PROCESS_INFORMATION{

    HANDLE hProcess;

    HANDLE hThread;

    DWORD dwProcessID;

    DWORD dwThreadID;

    }PROCESS_INFORMATION;

    在创建进程之前,我们首先要自己定义一个PROCESS_INFORMATION变量,然后使用它的地址调用CreateProcess()函数,CreateProcess函数在返回之前会出事化结构成员。这样我们就可以的到进程与主线程的句柄和ID了。

    PROCESS_INFORMATION pi;

    CreateProcess(……,&pi);

    接下来就可以通过pi来获取进程与主线程的句柄和ID。

    //创建线程函数

    HANDLE CreateThread(

    PSECURITY_ATTRIBUTES psa,

    DWORD cbStackSize,

    PTHREAD_START_ROUTINE pfnStartAddr,

    PVOID pvParam,

    DWORD dwCreateFlags,

    PDWORD pdwThreadID

    );

    该函数的返回值就是创建的新线程的句柄,最后一个参数即为线程ID。

    接下来介绍一下在Windows系统中如何获取进程/线程的伪句柄。

    Windows提供了两个函数来获取进程/线程的伪句柄。

    HANDLE GetCurrentProcess(); //获取进程伪句柄

    HANDLE GetCurrentThread(); //获取线程伪句柄

    调用这两个函数会返回进程/线程内核对象的一个伪句柄,不会在进程句柄表中新建句柄,同时也不会增加进程/线程内核对象计数。

    当然如果使用伪句柄进行CloseHandle()函数调用,CloseHandle会忽略此次调用。

    接下来介绍将伪句柄转换为真实句柄。

    //复制内核对象句柄函数

    BOOL DuplicateHandle(

    HANDLE hSourceProcess,

    HANDLE hSource,

    HANDLE hTargetProcess,

    HANDLE phTarget,

    DWORD dwDesiredAccess,

    BOOL bInheritHandle,

    DWORD dwOptions

    );

    这个函数获得一个进程句柄表中的一个记录项,然后在另一个句柄表中创建这个记录项的副本。

    第一个参数hSourceProcess和第三个参数hTargetProcess是内核对象句柄,而且必须是进程内核对象。

    第二个参数hSource可以是任何类型内核对象的句柄,但是必须和第一个参数所代表的进程相关。

    第四个参数用来接收复制的句柄值。

    最后三个参数用来指定内核对象在目标进程中的句柄表项,使用何种访问权限和继承标志。

    若最后一个参数指定为DUPLICATE_SAME_ACCESS,表明复制后的句柄与原句柄具有相同的访问权限。

    //获取线程句柄

    HANDLE hThread;

    DuplicateHandle(

    GetCurrentProcess(),

    GetCurrentThread(),

    GetCurrentProcess(),

    &hThread,

    0,

    FALSE,

    DUPLICATE_SAME_ACCESS

    );

    //获取进程句柄

    HANDLE hProcess;

    DuplicateHandle(

    GetCurrentProcess(),

    GetCurrentProcess(),

    GetCurrentProcess(),

    &hProcess,

    0,

    FALSE,

    DUPLICATE_SAME_ACCESS

    );

    可以看到,获取进程和线程句柄只是传入DuplicateHandle()的第二个参数不同。但是这个函数会增加内核对象计数,所以在使用完句柄后需要调用CloseHandle()使句柄计数减一。

  • 相关阅读:
    如何在ProXmoX VE 下虚拟机安装 黑群晖 DSM 6.1.6
    MySQL数据库(六) —— SQL注入攻击、视图、事物、存储过程、流程控制
    MySQL数据库(五)—— 用户管理、pymysql模块
    MySQL数据库(四)—— 记录相关操作之插入、更新、删除、查询(单表、多表)
    MySQL数据库(三)—— 表相关操作(二)之约束条件、关联关系、复制表
    MySQL数据库(二)——库相关操作、表相关操作(一)、存储引擎、数据类型
    MySQL数据库(一)—— 数据库介绍、MySQL安装、基础SQL语句
    并发编程(六)——进程/线程池、协程、gevent第三方库
    并发编程(五)——GIL全局解释器锁、死锁现象与递归锁、信号量、Event事件、线程queue
    并发编程(四)——线程、开启线程、守护线程、线程互斥锁
  • 原文地址:https://www.cnblogs.com/wanhuan/p/5398991.html
Copyright © 2011-2022 走看看