
 驱动给指定进程提升权限+降权原理及实现
 

2021在线班
郁金香灬老师 QQ 150330575
交流群:158280115

  R3
  NtQuerySystemInformation//16遍历句柄
  NtQueryInformationProcess //句柄转PID
  NtQueryObject//获取句柄信息 类型 名字
  DuplicateHandle//把目标进程的句柄复制到当前进程  类似于内存映射
  
NTDLL.DLL中有一个函数叫 NtQueryInformationProcess，用它可以将指定类型的进程信息拷贝到某个缓冲。其原型如下：
NTSYSAPI
NTSTATUS
NTAPI
NtQueryInformationProcess (
IN HANDLE ProcessHandle, // 进程句柄
IN PROCESSINFOCLASS InformationClass, // 信息类型
OUT PVOID ProcessInformation, // 缓冲指针
IN ULONG ProcessInformationLength, // 以字节为单位的缓冲大小
OUT PULONG ReturnLength OPTIONAL // 写入缓冲的字节数
);
 
 
DuplicateHandle 
在指出一个现有系统对象当前句柄的情况下，为那个对象创建一个新句柄。当前句柄可能位于一个不同的进程

  // 遍历进程句柄_R3.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<Windows.h>
#include<string>
#include"NtDefs.h"

 

using namespace std;






//进程句柄转PID
DWORD HandleToPid(IN HANDLE hProcess)
{
	_PROCESS_BASIC_INFORMATION pbi = { 0 }; //NTDEFS::SYSTEM_BASIC_INFORMATION 	NTDEFS::
#define ProcessBasicInformation 0

	//NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(_PROCESS_BASIC_INFORMATION), 0);
	//返回0表示成功
	NTSTATUS status = NtQueryInformationProcess(hProcess,
		ProcessBasicInformation,
		(PVOID)&pbi,
		sizeof(PROCESS_BASIC_INFORMATION),
		NULL);
	printf("hProcess=%X,status=%X\n", hProcess, status);
	if (!status)
	{
		return (DWORD)pbi.UniqueProcessId;
	}
	printf("hProcess=%p,pbi->UniqueProcessId=%lld\n", hProcess, pbi.UniqueProcessId);
	return 0;
}




void GetSystemHandleInformation(NTDEFS::SYSTEM_HANDLE_INFORMATION* pshi)//16
{

	//cout << "\t\t16 SystemHandleInformation" << endl;
	printf("GetSystemHandleInformation 句柄数量=%d\n", pshi->NumberOfHandles); //一般有几万个
	//getchar();
	NTDEFS::OBJECT_NAME_INFORMATION*szName = (NTDEFS::OBJECT_NAME_INFORMATION*)malloc(1000);
	NTDEFS::OBJECT_NAME_INFORMATION*szType = (NTDEFS::OBJECT_NAME_INFORMATION*)malloc(1000);

	for (UINT i = 0; i < pshi->NumberOfHandles; i++)
	{


		//	if ((int)pshi->Handles[i].CreatorBackTraceIndex ==11)
		//if (pshi->Handles[i].UniqueProcessId == 6652)
		{



			HANDLE newHandle = NULL;
			DWORD dwFlags1 = 0;
			DWORD dwFlags2 = 0;
			DuplicateHandle(
				OpenProcess(PROCESS_ALL_ACCESS, FALSE, pshi->Handles[i].UniqueProcessId),
				(HANDLE)pshi->Handles[i].HandleValue,
				GetCurrentProcess(),
				&newHandle,
				DUPLICATE_SAME_ACCESS,
				FALSE,
				DUPLICATE_SAME_ACCESS);
			if (newHandle)
			{


				NTSTATUS status1 = NtQueryObject(newHandle, NTDEFS::ObjectNameInformation, szName, 512, &dwFlags1);
				NTSTATUS status2 = NtQueryObject(newHandle, NTDEFS::ObjectTypeInformation, szType, 128, &dwFlags2);

	 
				if (_wcsicmp(szType->Name.Buffer, L"Process") == 0)
				{
		 
					DWORD 句柄目标进程PID = HandleToPid(newHandle);// (HANDLE)pshi->Handles[i].HandleValue);
					wprintf(L"<szType=%s szName=%s> Process句柄=%X  所属进程=%d 句柄目标进程PID=%d\n\n",
						szType->Name.Buffer,
						szName->Name.Buffer,
						pshi->Handles[i].HandleValue,
						pshi->Handles[i].UniqueProcessId,
						句柄目标进程PID);
					//getchar();
				}//if1

			} //--if2


		}

	}//end for
	printf("Line=%d\n", __LINE__);
	getchar();
	free(szName);
	free(szType);
}

//SystemHandleInformation =16
void 遍历进程句柄()
{
	NTSTATUS status = STATUS_SUCCESS;
	ULONG retlen = 0;
	ULONG SystemInformationLength = 0;
	NTDEFS::SYSTEM_HANDLE_INFORMATION info;
	status = NtQuerySystemInformation(NTDEFS::SystemHandleInformation, &info, sizeof(NTDEFS::SYSTEM_HANDLE_INFORMATION), &retlen);
	
	//retlen
	HLOCAL hMem = LocalAlloc(0, retlen);
	printf("retlen=%X hMem=%p\n", retlen, hMem);
	if (hMem)
	{
		NTDEFS::SYSTEM_HANDLE_INFORMATION* pHandleInfo = (NTDEFS::SYSTEM_HANDLE_INFORMATION*)LocalLock(hMem);
		if (pHandleInfo)
		{
			memset(pHandleInfo, 0, retlen);
			status = NtQuerySystemInformation(NTDEFS::SystemHandleInformation, pHandleInfo, retlen, &retlen);
			if (NT_SUCCESS(status))
			{
				GetSystemHandleInformation(pHandleInfo);
			}
		}
		LocalFree(hMem);
	}//end
	return;
}

//SystemHandleInformation
int main()
{
	遍历进程句柄();
	return 1;

}