首页
社区
课程
招聘
[求助]WIN7下复制句柄失败?
发表于: 2012-12-29 11:38 6623

[求助]WIN7下复制句柄失败?

2012-12-29 11:38
6623
HANDLE LzOpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle, DWORD dwProcessId)
{
	NTSTATUS status=0;
	char *pBuf=NULL;
	BOOLEAN  wasEnabled;
	DWORD buflen=0x10000,needlen=0;
	DWORD HandleCnt=0;
	HANDLE hRetProcess=0,hOwnerProc,hTmp;
	PSYSTEM_HANDLE_INFORMATION pSysHandleInfo=NULL;
	PROCESS_BASIC_INFORMATION BasePsInfo;
	OBJECT_ATTRIBUTES objatr;
	CLIENT_ID Cid;
	//提升调试权限,否则有些进程,比如服务进程打不开
	RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE,TRUE,FALSE,&wasEnabled);
	InitializeObjectAttributes(&objatr,0,0,0,0);
	//先尝试正常方式打开
	Cid.UniqueProcess=(HANDLE)dwProcessId;
	Cid.UniqueThread=0;
	/*status=ZwOpenProcess(&hRetProcess,dwDesiredAccess,&objatr,&Cid);//尝试直接打开
	if (NT_SUCCESS(status))
	{
		return hRetProcess;
	}
	//不成功,尝试把PID加1再打开,加2,加3也可以
	//理由:有些HOOK函数中过滤PID时不完善,正确的做法应该是先用掩码忽略低两位之后再比较
	Cid.UniqueProcess=(HANDLE)(dwProcessId+1);
	status=ZwOpenProcess(&hRetProcess,dwDesiredAccess,&objatr,&Cid);//尝试直接打开pid+1
	if (NT_SUCCESS(status))
	{
		return hRetProcess;
	}
	*/
	//都不成功,就找别的进程中的Handle,这才是本代码的核心, 这些Handle大部分是在Csrss.exe中
	do 
	{
		//申请查询句柄信息所需的内存
		ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&pBuf,0,&buflen,MEM_COMMIT,PAGE_READWRITE);
		//查询系统句柄信息,类型为16
		status=ZwQuerySystemInformation(SystemHandleInformation,(PVOID)pBuf,buflen,&needlen);
		if (status==STATUS_SUCCESS)
		{
			break;
		}
		//不成功,则释放内存
		//这里只要一块大内存够放这些内容就行,或者直接申请一块足够大的也可以
		//返回的needlen可以做为参考
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&pBuf,&buflen,MEM_RELEASE);
		//然后把要申请的内存大小乘2,直至成功为止
		buflen*=2;
		pBuf=NULL;
	} while(1);
	//返回的缓冲区内容的第一个DWORD是总的句柄的个数
	HandleCnt=*(DWORD*)pBuf;
	//跳过句柄计数,才是真正的开始
	pSysHandleInfo=(PSYSTEM_HANDLE_INFORMATION)((char*)pBuf+sizeof(DWORD));
	for (DWORD i=0;i<HandleCnt;i++)
	{
		//只验证类型为PROCESS的,值为5
		if (pSysHandleInfo->ObjectTypeNumber==OB_TYPE_PROCESS)
		{
			//打开这个句柄的所有者进程,要复制过来才能查询,否则只能看不能摸~
			Cid.UniqueProcess=(HANDLE)(pSysHandleInfo->ProcessId);
			Cid.UniqueThread=0;
			status=ZwOpenProcess(&hOwnerProc,PROCESS_ALL_ACCESS,&objatr,&Cid);
			if (NT_SUCCESS(status))
			{
				printf("打开进程成功\n");
				//打开成功,复制句柄到本进程,这里用了PROCESS_ALL_ACCESS以避免权限问题
				status=ZwDuplicateObject(hOwnerProc,
					(HANDLE)(pSysHandleInfo->Handle),
					NtCurrentProcess(),
					&hTmp,
					PROCESS_ALL_ACCESS,
					FALSE,
					0);
				if (NT_SUCCESS(status))
				{
					printf("复制句柄成功\n");
					//复制成功,查询此句柄所对应的进程PID,查询基本信息即可
					status=ZwQueryInformationProcess(hTmp,ProcessBasicInformation,&BasePsInfo,sizeof(PROCESS_BASIC_INFORMATION),NULL);
					if (NT_SUCCESS(status))
					{
						//成功,判断其PID
						if (BasePsInfo.UniqueProcessId==dwProcessId)
						{
							//句柄所有者是我们要的目标进程,再按所需的权限复制过来
							ZwDuplicateObject(hOwnerProc,
								(HANDLE)(pSysHandleInfo->Handle),
								NtCurrentProcess(),
								&hRetProcess,
								0,
								FALSE,
								PROCESS_ALL_ACCESS);
							//关掉为复制而打开的句柄所有者的句柄引用
							ZwClose(hOwnerProc);
							break;
						}
						
					}

				}
			}
		}
		pSysHandleInfo++;//指向下一个结构
	}
	if (pBuf)
	{
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&pBuf,&buflen,MEM_RELEASE);
	}
	return hRetProcess;
}


这段代码在XP系统下正常,在32位WIN7系统下就无法使用ZwDuplicateObject复制其他进程中的句柄,提升自身进程权限为Debug权限也是一样失败。何故?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 575
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
以管理员身份运行试试
2012-12-31 10:00
0
雪    币: 29
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
早试过了,一样的。
2013-1-7 09:58
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
全部失败还是部分句柄失败?WIN7上有一些对象是不能复制的
2013-1-7 10:31
0
游客
登录 | 注册 方可回帖
返回
//