复制对象句柄DuplicateHandle(文件占坑)
DuplicateHandle文档化解释
The DuplicateHandle function duplicates an object handle. The duplicate handle refers to the same object as the original handle. Therefore, any changes to the object are reflected through both handles. For example, the current file mark for a file handle is always the same for both handles.
使用 DuplicateHandle 函数将源进程 ProcessHandle 的句柄表中的信息如对象句柄 MutexHandle 复制到当前目标进程的句柄表中
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle, // handle to source process 源进程句柄
HANDLE hSourceHandle, // handle to duplicate 被拷贝的信息(应与源进程句柄的进程有关)
HANDLE hTargetProcessHandle, // handle to target process 目标进程句柄
LPHANDLE lpTargetHandle, // duplicate handle 用来接收被拷贝的信息_Out_
DWORD dwDesiredAccess, // requested access 传0
BOOL bInheritHandle, // handle inheritance option 处理继承选项传FALSE或者TURE
DWORD dwOptions // optional actions 如DUPLICATE_SAME_ACCESS,让目标进程对被拷贝的句柄的内核对象也有访问权限
);
一、参数说明:
调用DuplicateHandle时,它的第一个参数和第三个参数 (hSourceProcessHandle 和 hTargetProcessHandle) 是进程内核对象句柄。这两个句柄本身必须相对于调用DuplicateHandle函数的那个进程。此外,这两个参数标识的必须是进程内核对象;如果我们传递的句柄指向的是其他类型的内核对象,函数调用就会失败。我们将在第4章详细讨论进程内核对象。就目前来说,我们只需知道一旦启动一个新的进程,系统就会创建一个进程内核对象。
第二个参数 hSourceHandle 是指向任何类型的内核对象的一个句柄。但是,它的句柄值一定不能与调用 DuplicateHandle 函数的那个进程相关(不能指向目标进程 TargetProcess 的内核对象)。相反,该句柄必须与 hSourceProcessHandle 句柄所标识的源进程相关(例如源进程创建了文件,返回了文件对象句柄)。函数会将源进程中的指定的句柄信息(FileHandle)复制到 hTargetProcessHanle 所标识的目标进程的句柄表中。
第四个参数是 phTargetHandle ,它是一个 HANDLE 变量的地址,用来接收复制得到的 HANDLE 值。
二、参考使用:
[B进程]
参考使用1:将伪句柄转换成真实句柄
HANDLE PseudoProcessHandle = GetCurrentProcess(); //获得伪句柄 -1
HANDLE RealProcessHandle = NULL; //将伪句柄转换成真实句柄
DuplicateHandle(GetCurrentProcess(), PseudoProcessHandle, GetCurrentProcess(), &RealProcessHandle,
0, FALSE, DUPLICATE_SAME_ACCESS);
//通过上面的函数就可以将一个进程中的一个线程的伪句柄转换成正真的句柄
//DuplicateHandle递增了内核对象的句柄数最好要调用CloseHandle();
参考使用2:拷贝当前进程中的指定对象的句柄到目标进程中
HANDLE v1 = NULL;
//DuplicateHandle拷贝当前进程中的FileHandle句柄到目标进程中
BOOL IsOk = DuplicateHandle(GetCurrentProcess(), FileHandle, ProcessHandle, &v1, 0, FALSE, DUPLICATE_SAME_ACCESS);
//当前进程句柄ProcessHandle
//被拷贝的文件句柄(当前进程里面创建的文件句柄)
//拷贝到目标进程的句柄
//v1也是句柄,用来接收目标进程上拷贝上的句柄的数
//DUPLICATE_SAME_ACCESS,让目标进程对被拷贝的句柄的内核对象也有访问权限
参考使用3:拷贝目标进程句柄表中指定句柄到当前进程句柄表中
//如何知道进程
_tscanf(_T("%d"), &ProcessIdentify); // 目标进程id
_tscanf(_T("%d"), &MappingHandle); // 目标进程句柄表下的MappingHandle //根据目标进程的ID打开目标进程
ProcessHandle = SunOpenProcess(PROCESS_DUP_HANDLE, FALSE, ProcessIdentify);
//Anti策略
//DuplicateHandle获取进程虚拟空间地址
BOOL IsOk = DuplicateHandle(ProcessHandle, MappingHandle, GetCurrentProcess(), &v1, 0, FALSE, DUPLICATE_SAME_ACCESS);
三、其他说明
使用DuplicateHandle函数(来复制内核对象句柄)所遇到的问题和继承(内核对象句柄)时同样:目标进程不知道它现在能访问一个新的内核对象。所以,进程C必须以某种方式来通1进程T,告诉它现在可以访问一个内核对象了,而且必须使用某种形式的进程间通信机制,将hObj中的句柄值传给进程T,显然,使用命令行参数或者更改进程T的环境变量是行不通的,因为进程已经启动并开始运行了。我们必须使用窗口消息或者其他进程间通信(IPC)机制。
四、演示程序
将当前进程EProcess里的FileHandle的句柄拷贝到另一个进程explore.exe身上,并使其拥有对被拷贝句柄的内核对象的访问权限。
代码测试:
重新生成文件,将在文件目录下生成一个ReadMe文件,打开文件,再运行exe程序,发现无法删除此文件。explorer进程不关闭,文件句柄关不掉,FIleObject就关不掉,所以无法关闭记事本。
在代码里就是把第二参数句柄粘贴到第三参数身上,就相当于你把自己的句柄拷贝到了别人身上了,所以就存在占坑现象,第二参数句柄指向的内核对象关闭不了,其对应的进程无法关闭。
#include "DuplicateHandle.h" BOOL __EnableDebugPrivilege = TRUE; //定义参数
void _tmain(int argc, TCHAR* argv[], TCHAR *envp[])
{
Sub_1();
return;
} void Sub_1()
{ HANDLE ProcessHandle = NULL; //打开一个进程,得到进程句柄
ProcessHandle = SunOpenProcess(PROCESS_DUP_HANDLE, FALSE, (HANDLE)10688); //explore.exe进程
//SunOpenProcess中需要提权函数SunEnableSunDebugPrivilege if (ProcessHandle == NULL)
{
goto Exit;
} HANDLE FileHandle = INVALID_HANDLE_VALUE;
//在当前进程中创建一个文件,返回文件句柄
FileHandle = CreateFile(_T("ReadMe.txt"), GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (FileHandle == INVALID_HANDLE_VALUE)
{
goto Exit;
} HANDLE v1 = NULL;
//DuplicateHandle拷贝当前进程中的FileHandle句柄到目标进程中
BOOL IsOk = DuplicateHandle(GetCurrentProcess(), FileHandle, ProcessHandle, &v1, 0,
FALSE, DUPLICATE_SAME_ACCESS);
//当前进程句柄ProcessHandle
//被拷贝的文件句柄(当前进程里面创建的文件句柄)
//拷贝到目标进程的句柄
//v1也是句柄,用来接收目标进程上拷贝上的句柄的数
//DUPLICATE_SAME_ACCESS,让目标进程对被拷贝的句柄的内核对象也有访问权限
if (FileHandle != INVALID_HANDLE_VALUE)
{
SunCloseHandle(FileHandle);
FileHandle = INVALID_HANDLE_VALUE;
}
Exit:
if (ProcessHandle != NULL)
{ SunCloseHandle(ProcessHandle);
ProcessHandle = NULL;
}
} /*提权函数*/
DWORD SunEnableSunDebugPrivilege(HANDLE ProcessHandle, BOOL IsEnable)
{
DWORD LastError;
HANDLE TokenHandle = 0; if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))
{
LastError = GetLastError();
if (TokenHandle)
SunCloseHandle(TokenHandle);
return LastError;
}
TOKEN_PRIVILEGES TokenPrivileges;
memset(&TokenPrivileges, 0, sizeof(TOKEN_PRIVILEGES));
LUID v1;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &v1))
{
LastError = GetLastError();
SunCloseHandle(TokenHandle);
return LastError;
}
TokenPrivileges.PrivilegeCount = 1;
TokenPrivileges.Privileges[0].Luid = v1;
if (IsEnable)
TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
TokenPrivileges.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
LastError = GetLastError();
SunCloseHandle(TokenHandle);
return LastError;
} HANDLE SunOpenProcess(DWORD DesiredAccess, BOOL IsInheritHandle, HANDLE ProcessIdentify)
{ //提权
if (__EnableDebugPrivilege) //全局变量__EnableDebugPrivilege
{
SunEnableSunDebugPrivilege(GetCurrentProcess(), TRUE);
} //打开进程,根据目标进程的进程ID得到进程句柄
HANDLE ProcessHandle = OpenProcess(DesiredAccess, IsInheritHandle, (DWORD)ProcessIdentify); DWORD LastError = GetLastError(); //关闭权限
if (__EnableDebugPrivilege)
{
SunEnableSunDebugPrivilege(GetCurrentProcess(), FALSE);
}
SetLastError(LastError);
return ProcessHandle;
} BOOL SunCloseHandle(HANDLE HandleValue)
{
DWORD HandleFlags;
if (GetHandleInformation(HandleValue, &HandleFlags)
&& (HandleFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != HANDLE_FLAG_PROTECT_FROM_CLOSE)
return !!CloseHandle(HandleValue);
return FALSE;
}
复制对象句柄DuplicateHandle(文件占坑)的更多相关文章
- 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间
[源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...
- 插件开发之360 DroidPlugin源码分析(四)Activity预注册占坑
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52258434 在了解系统的activity,service,broa ...
- C#对象与XMl文件之间的相互转换
C#提供三种序列化方式,分别为: 1.是使用BinaryFormatter进行串行化: 2.使用SoapFormatter进行串行化: 3.使用XmlSerializer进行串行化.其中对于Binar ...
- windows内核对象句柄
内核对象用于管理进程.线程和文件等诸多种类的大量资源,每一个内核对象都只是一个句内存快,它由操作系统内核分配,并只能右操作系统内核访问.这个内存块是一个数据结构,其维护着与对象相关的信息,其中少数成员 ...
- C#压缩文件夹坑~
dotNet疯狂之路No.29 今天很残酷,明天更残酷,后天很美好,但是绝大部分人是死在明天晚上,只有那些真正的英雄才能见到后天的太阳. We're here to put a dent in t ...
- 插件开发之360 DroidPlugin源码分析(五)Service预注册占坑
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52264977 在了解系统的activity,service,broa ...
- 插件占坑,四大组件动态注册前奏(三) 系统BroadCast的注册发送流程
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52204143 前言:为什么要了解系统Activity,Service,BroadCas ...
- 插件占坑,四大组件动态注册前奏(二) 系统Service的启动流程
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52203903 前言:为什么要了解系统Activity,Service,BroadCas ...
- 插件占坑,四大组件动态注册前奏(一) 系统Activity的启动流程
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52190050 前言:为什么要了解系统Activity,Service,,BroadCa ...
- java:利用java的输入/输出流将一个文件的每一行+行号复制到一个新文件中去
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
随机推荐
- SAE 最佳实践范本:助力视野数科进入云原生“快车道”
阿里云生态金融科技行业标杆 -- 2021 年,云原生的商业价值正在被加速释放. 一个公认的事实是,Serverless 是当下云原生方向内绝对的亮点.可以看作,它的出现,让企业用户真正地免除 ...
- VUE里使用iframe在更改了src之后对应的网页并未刷新解决方案
在vue 里使用iframe,在更新src后页面并未刷新, 在更改iframe src属性值之前加上这一句即可 document.getElementById(iframe的id).contentWi ...
- ACP 知识点总结
记录下学习ACP过程不断遇到的且需要记录的知识点: 在阿里云专有网络VPC创建之后,路由器也是随着VPC一起自动创建,所以不需要手动创建,这个时候需要继续创建交换机才能在交换机种创建其他云产品. 7层 ...
- 项目使用 GlobalExceptionHandler 与 @RestControllerAdvice自定义异常 二
未经博主允许不得转载: 自定义异常,不仅需要定义符合自己业务的异常状态码,也需要定义自己项目中的异常封装.记录下自己手敲代码中的异常封装: 1.定义一个枚举类,枚举类中定义状态码及状态码描述,再定义一 ...
- AHB2APB设计
AHB2APB Bridge位置 AHB子系统时钟在200Mhz左右,APB时钟在几十Khz到几十Mhz 所以要进行跨时钟域处理,从AHB高时钟频率转到APB低时钟频率 AHB2APB Bridge规 ...
- K8S增加限制后的启动时间验证
K8S增加限制后的启动时间验证 背景 前段时间看了下JVM载linux上面的启动时间, 进行过一些验证. 最近想着能够验证一下K8S上面的启动相关的信息 所以就整理了一下. 虽然没有特别好的结论, 但 ...
- [转帖]Linux中的inode到底是什么
https://www.jianshu.com/p/6aa4d7ef17de inode 是什么? 要了解 Linux 操作系统上的 inode 前,我们先来说说 Linux操作系统上的文件.对于 L ...
- Redis monitor命令
MONITOR Syntax MONITOR Available since: 1.0.0 Time complexity: ACL categories: @admin, @slow, @dange ...
- DBeaver连接国产信创数据库的步骤
DBeaver连接国产信创数据库的步骤 本次连接使用的数据库类型 1.达梦 2.神通 3.人大金仓 4.瀚高 安装DBeaver 通过官网或者是其他网站下载最新的数据库介质 之后的操作为: 这次不感谢 ...
- 记录TritonServer部署多模型到多GPU踩坑 | 京东云技术团队
一.问题是怎么发现的 部署chatglm2和llama2到一个4*V100的GPU机器上遇到问题 config.pbtxt 中设置模型分别在指定gpu上部署实例配置不生效 如以下配置为在gpu0上部署 ...