主要是依靠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. [转帖]MySQL快速备份表

    https://www.cnblogs.com/JaxYoun/p/14264593.html 1.复制表结构及数据到新表 CREATE TABLE 新表 SELECT * FROM 旧表 这种方法会 ...

  2. [转帖]比较不同CPU下的分支预测

    https://plantegg.github.io/2023/04/16/%E6%AF%94%E8%BE%83%E4%B8%8D%E5%90%8CCPU%E4%B8%8B%E7%9A%84%E5%8 ...

  3. 申威下单盘SSD与四块盘RAID5的性能测试结果

    申威下单盘SSD与四块盘RAID5的性能测试结果 背景 背景不在说了 申威服务器.. 结论 天坑 做了raid写入性能下降明显. 充分怀疑驱动不行. 四快盘的raid5 跟单盘的读几乎没区别. 感觉这 ...

  4. [转帖]ansible 安装 K8S

    作者:山河已无恙链接:https://www.zhihu.com/question/315497851/answer/2898814729来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...

  5. [转帖]Python-Mock接口测试

    https://www.cnblogs.com/zhangwuxuan/p/12928850.html 前言 今天跟小伙伴们一起来学习一下如何编写Python脚本进行mock测试. 什么是mock? ...

  6. 【转帖】SRE 高延迟问题的罪魁祸首 System.gc()

    https://www.infoq.cn/article/lXTRgYb9ecVBu*72fT7O jstact -gccause pid 3000 30 01 案例一: 某日,支付平台的开发人员找到 ...

  7. 【转帖】基于官方rpm包方式安装Oracle19c

    https://blog.whsir.com/post-5489.html   本文基于Centos7.x环境,通过官方提供的rpm包来安装19c 1.下载Oracle19c安装包 https://w ...

  8. Linux部分参数的学习

    Linux部分参数的学习 简介 之前总结过很多Nginx或者是部署软件时的一些注意事项. 但是感觉对linux系统参数部分掌握的不是很好. 今天周末想着整理一下,作为备忘. limits.conf i ...

  9. Arthas 超简单离线使用教程

    简介 Arthas 是阿里巴巴开源的一套监控java应用的工具 官网的文档地址: https://arthas.aliyun.com/doc/ 官方的简介说明: Arthas 是Alibaba开源的J ...

  10. 使用Python调用Nessus 接口实现自动化扫描

    @ 目录 认证 策略模板配置 创建策略模板 任务 创建任务 启动/停止任务 获取扫描结果 获取漏洞信息 获取漏洞输出信息与漏洞知识库信息 最后总结 之前在项目中需要接入nessus扫描器,研究了一下n ...