主要是依靠NtQueryObject函数,其中需要传入ObjectBasicInformation参数

PUBLIC_OBJECT_BASIC_INFORMATION结构包含可用于对象的全部信息的子集。

typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
ULONG Attributes;
ACCESS_MASK GrantedAccess; //指定一个掩码,该掩码代表对对象的授予访问权限
ULONG HandleCount;
ULONG PointerCount;
ULONG Reserved[10];
} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;

Demo:

#include <iostream>
#include <string> #include <Windows.h>
#include <TlHelp32.h>
#include <Psapi.h>
#include <Shlwapi.h> using namespace std; #pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "psapi.lib") #pragma region NT Structures #define NT_SUCCESS(x) ((x) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004 #define SystemHandleInformation 16
#define ObjectBasicInformation 0
#define ObjectNameInformation 1
#define ObjectTypeInformation 2 typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
ULONG Attributes;
ACCESS_MASK GrantedAccess;
ULONG HandleCount;
ULONG PointerCount;
ULONG Reserved[10]; // reserved for internal use
} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION; typedef NTSTATUS(NTAPI *_NtQuerySystemInformation)(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
typedef NTSTATUS(NTAPI *_NtDuplicateObject)(
HANDLE SourceProcessHandle,
HANDLE SourceHandle,
HANDLE TargetProcessHandle,
PHANDLE TargetHandle,
ACCESS_MASK DesiredAccess,
ULONG Attributes,
ULONG Options
);
typedef NTSTATUS(NTAPI *_NtQueryObject)(
HANDLE ObjectHandle,
ULONG ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength
); typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING; typedef struct _SYSTEM_HANDLE
{
ULONG ProcessId;
BYTE ObjectTypeNumber;
BYTE Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE; typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG HandleCount;
SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; typedef enum _POOL_TYPE
{
NonPagedPool,
PagedPool,
NonPagedPoolMustSucceed,
DontUseThisType,
NonPagedPoolCacheAligned,
PagedPoolCacheAligned,
NonPagedPoolCacheAlignedMustS
} POOL_TYPE, *PPOOL_TYPE; typedef struct _OBJECT_TYPE_INFORMATION
{
UNICODE_STRING Name;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG TotalPagedPoolUsage;
ULONG TotalNonPagedPoolUsage;
ULONG TotalNamePoolUsage;
ULONG TotalHandleTableUsage;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
ULONG HighWaterPagedPoolUsage;
ULONG HighWaterNonPagedPoolUsage;
ULONG HighWaterNamePoolUsage;
ULONG HighWaterHandleTableUsage;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccess;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
USHORT MaintainTypeList;
POOL_TYPE PoolType;
ULONG PagedPoolUsage;
ULONG NonPagedPoolUsage;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; #pragma endregion // for getting an address of a procedure in memory.
PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
{
return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
} DWORD FindProcessId(const std::string processName)
{
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo); HANDLE processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (processSnapshot == INVALID_HANDLE_VALUE)
return 0; Process32First(processSnapshot, &processInfo);
if (!processName.compare(processInfo.szExeFile))
{
CloseHandle(processSnapshot);
return processInfo.th32ProcessID;
} while (Process32Next(processSnapshot, &processInfo))
{
if (!processName.compare(processInfo.szExeFile))
{
CloseHandle(processSnapshot);
return processInfo.th32ProcessID;
}
} CloseHandle(processSnapshot);
return 0;
} int main()
{
while (1)
{
/* string input;
cout << "Please enter a name of a process: ";
cin >> input;*/ DWORD pid = 0;
_NtQuerySystemInformation NtQuerySystemInformation =
(_NtQuerySystemInformation)GetLibraryProcAddress(const_cast<char*>("ntdll.dll"), const_cast<char*>("NtQuerySystemInformation"));
_NtDuplicateObject NtDuplicateObject =
(_NtDuplicateObject)GetLibraryProcAddress(const_cast<char*>("ntdll.dll"), const_cast<char*>("NtDuplicateObject"));
_NtQueryObject NtQueryObject =
(_NtQueryObject)GetLibraryProcAddress(const_cast<char*>("ntdll.dll"), const_cast<char*>("NtQueryObject")); NTSTATUS status;
PSYSTEM_HANDLE_INFORMATION handleInfo;
ULONG handleInfoSize = 0x10000;
HANDLE processHandle;
ULONG i; processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid); handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); while ((status = NtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2); for (i = 0; i < handleInfo->HandleCount; i++)
{
SYSTEM_HANDLE handle = handleInfo->Handles[i];
HANDLE dupHandle = NULL;
POBJECT_TYPE_INFORMATION objectTypeInfo;
PVOID objectNameInfo;
UNICODE_STRING objectName;
ULONG returnLength; /*if (handle.ProcessId != pid)
continue;*/ NT_SUCCESS(NtDuplicateObject(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, 0, 0, 0));
PUBLIC_OBJECT_BASIC_INFORMATION pb;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&pb, sizeof(pb)); ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
CreateProcess(NULL, const_cast<char*>("C:\\WINDOWS\\system32\\calc.exe"), NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi); objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
NTSTATUS err_1 = NtQueryObject(pi.hProcess, ObjectBasicInformation, &pb, sizeof(pb), NULL); DWORD access = pb.GrantedAccess;
if (handle.GrantedAccess == 0x0012019f)
{
std::free(objectTypeInfo);
CloseHandle(dupHandle);
continue;
} objectNameInfo = malloc(0x1000); if (!NT_SUCCESS(NtQueryObject(pi.hProcess, ObjectNameInformation, objectNameInfo, 0x1000, &returnLength)))
{
objectNameInfo = realloc(objectNameInfo, returnLength);
if (!NT_SUCCESS(NtQueryObject(
dupHandle,
ObjectNameInformation,
objectNameInfo,
returnLength,
NULL
)))
{
std::free(objectTypeInfo);
std::free(objectNameInfo);
CloseHandle(dupHandle);
continue;
}
}
objectName = *(PUNICODE_STRING)objectNameInfo;
wstring ObjectBuffer = objectTypeInfo->Name.Buffer; // We are only interested about handles to files & processes
if (ObjectBuffer.find(L"File") != wstring::npos || ObjectBuffer.find(L"Process") != wstring::npos)
{ HANDLE CurrentProcess = GetCurrentProcess();
HANDLE procHandle = OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, handle.ProcessId); HANDLE DuplicatedHandle = 0; // Duplicating the handle, now we can do basically anything with it.
if (DuplicateHandle(procHandle, (HANDLE)handle.Handle, CurrentProcess, &DuplicatedHandle, 0, false, DUPLICATE_SAME_ACCESS))
{
WCHAR NameBlock[256];
wstring block = NameBlock;
K32GetProcessImageFileNameW(DuplicatedHandle, NameBlock, 256); PathStripPathW(NameBlock);
wcout << L"Handle to " << ObjectBuffer << ": " << NameBlock << " Id: " << GetProcessId(DuplicatedHandle) << endl;
}
}
std::free(objectTypeInfo);
std::free(objectNameInfo);
CloseHandle(dupHandle);
} std::free(handleInfo);
CloseHandle(processHandle);
cin.get();
}
return 0;
}

大部分用不到,只需要关注NtQueryObject部分就行了。 这个demo是测试createprocess获得的句柄权限,结果是pb.GrantedAccess = 0x1FFFFF,代表有全部权限,这与文档中说的是一样的

The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object. When you call the OpenProcess function, the system checks the requested access rights against the DACL in the process's security descriptor. When you call the GetCurrentProcess function, the system returns a pseudohandle with the maximum access that the DACL allows to the caller.

参考: https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights

C++检测句柄的权限的更多相关文章

  1. BeginInvoke之前检测句柄

    只要在BeginInvoke方法的调用语句前再加一句:IntPtr i = this.Handle;就OK了,这比死循环配合this.IsHandleCreated的判断方法更简洁,因为this.Ha ...

  2. 内核对象&句柄&泄漏&检测

    今天看到这个问题如何评价王垠的 <讨厌的 C# IDisposable 接口>? - 王垠(人物),答案被歪到windows 内核对象和句柄,答案中谈的太浅显而且有误.翻出陈年老文章(此文 ...

  3. Android 6.0 - 动态权限管理的解决方案

    Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...

  4. Android 开发技巧 - Android 6.0 以上权限大坑和权限检查基类封装

    简单介绍 关于运行时权限的说法,早在Google发布android 6.0的时候,大家也听得蛮多的.从用户的角度来讲,用户是受益方,更好的保护用户的意思,而对于开发者来说,无疑增加了工作量. 对于6. ...

  5. Android 6.0 权限管理

    google官方例子: https://github.com/googlesamples/android-RuntimePermissions Android 6.0在我们原有的AndroidMani ...

  6. Web应用程序系统的多用户权限控制设计及实现-项目架构【3】

    本章主要讲述Web权限管理系统的项目架构,及开发中需要的基本类和相关的CSS,JS文件. 1.1系统结构 本系统搭建开发工具为Visual Studio 2012,采用ASP.NET MVC 4.0技 ...

  7. android 自定义权限管理

    在Android6.0后有些权限就需要进行询问,虽然可以将targetSdkVersion设置成小于等于23,但是这样可能有些东西无法使用,所以要进行权限的管理. 实现逻辑:打开页面就询问权限,如果没 ...

  8. rest-framework之权限组件

    权限 权限 作用 : 校验用户是否有权限访问 检测权限肯定是在用户认证通过之后,所有可以直接在request中取出用户做判断 先定义一个类,继承 BasePermission. from rest_f ...

  9. Android PermissionUtils:运行时权限工具类及申请权限的正确姿势

    Android PermissionUtils:运行时权限工具类及申请权限的正确姿势 ifadai 关注 2017.06.16 16:22* 字数 318 阅读 3637评论 1喜欢 6 Permis ...

  10. .net程序和管理员权限的一些事

    1.对某个方法设置管理员权限运行(未考证)(假的,必须以管理员权限启动,不然报错) [PrincipalPermission(SecurityAction.Demand, Role = @" ...

随机推荐

  1. [转帖]Linux系统管理-crond、chkconfig、systemd、unit、target

    https://cloud.tencent.com/developer/article/1409845 10.23 linux任务计划cron crontab命令被用来提交和管理用户的需要周期性执行的 ...

  2. [转帖]Oracle AWR报告提取方法

    https://www.cnblogs.com/jyzhao/p/4030022.html 本文旨在用来指导项目人员自行提取Oracle数据库的AWR报告. 1.当前连接实例的AWR报告提取:@?/r ...

  3. Oracle Rac 的简单学习

    Oracle Rac 的简单学习 Oracle RAC的概念 Oracle RAC (Real Application Clusters) 是 Oracle 数据库管理系统的一个功能, 它允许将数据库 ...

  4. [转帖]prometheus的TCP alloc取值

    prometheus的TCP alloc取值 sockets: used:已使用的所有协议套接字总量 TCP: orphan:无主(不属于任何进程)的TCP连接数(无用.待销毁的TCP socket数 ...

  5. FIO的再学习-不同Raid,不同磁盘性能验证

    FIO的再学习-不同Raid性能验证 背景 发现自己对iodepth的和num_jobs的理解存在偏差 找了一些资料才发现自己很多地方做的不对. 这里找到一个新资料可以进行模拟数据库的测试 测试配置文 ...

  6. [转帖]linux--Segfault详解

    linux--Segfault详解 1 简介 1.1 段错误的定义 1.2 痛点 2 知识点 2.1 报错内容 2.2 error number 3 排除步骤(借助汇编) 3.1 日志确定错误类型 3 ...

  7. 【网络流,dp】Gym102220A Apple Business

    Problem Link 有一棵 \(n\) 个点的完全二叉树(点 \(i\) 的父亲是 \(\lfloor i/2\rfloor\)),第 \(i\) 个点有 \(a_i\) 个苹果.现在有 \(m ...

  8. vue动画appear 实现页面刚展示出来的时候,入场效果

    <style> /* 给动画添加一组过度效果 */ .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); } . ...

  9. 热门数据集提供【MNIST、鸢尾花、猫狗、CIFAR10、vegetables、Ox-Flowers17、pascalvoc】

    热门数据集提供[MNIST.鸢尾花.猫狗.CIFAR10.vegetables.Ox-Flowers17.pascalvoc] 简介: 鸢尾花数据集: 约150条数据,每条样本4个属性,共3个类别 M ...

  10. 如何控制Tomcat的catalina.out的大小

    catalina.out文件,数据主要来源为:System.out 和 System.err 在控制台上直接输出的信息. 编码时应避免使用System.out.println()和e.printSta ...