C++检测句柄的权限
主要是依靠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++检测句柄的权限的更多相关文章
- BeginInvoke之前检测句柄
只要在BeginInvoke方法的调用语句前再加一句:IntPtr i = this.Handle;就OK了,这比死循环配合this.IsHandleCreated的判断方法更简洁,因为this.Ha ...
- 内核对象&句柄&泄漏&检测
今天看到这个问题如何评价王垠的 <讨厌的 C# IDisposable 接口>? - 王垠(人物),答案被歪到windows 内核对象和句柄,答案中谈的太浅显而且有误.翻出陈年老文章(此文 ...
- Android 6.0 - 动态权限管理的解决方案
Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...
- Android 开发技巧 - Android 6.0 以上权限大坑和权限检查基类封装
简单介绍 关于运行时权限的说法,早在Google发布android 6.0的时候,大家也听得蛮多的.从用户的角度来讲,用户是受益方,更好的保护用户的意思,而对于开发者来说,无疑增加了工作量. 对于6. ...
- Android 6.0 权限管理
google官方例子: https://github.com/googlesamples/android-RuntimePermissions Android 6.0在我们原有的AndroidMani ...
- Web应用程序系统的多用户权限控制设计及实现-项目架构【3】
本章主要讲述Web权限管理系统的项目架构,及开发中需要的基本类和相关的CSS,JS文件. 1.1系统结构 本系统搭建开发工具为Visual Studio 2012,采用ASP.NET MVC 4.0技 ...
- android 自定义权限管理
在Android6.0后有些权限就需要进行询问,虽然可以将targetSdkVersion设置成小于等于23,但是这样可能有些东西无法使用,所以要进行权限的管理. 实现逻辑:打开页面就询问权限,如果没 ...
- rest-framework之权限组件
权限 权限 作用 : 校验用户是否有权限访问 检测权限肯定是在用户认证通过之后,所有可以直接在request中取出用户做判断 先定义一个类,继承 BasePermission. from rest_f ...
- Android PermissionUtils:运行时权限工具类及申请权限的正确姿势
Android PermissionUtils:运行时权限工具类及申请权限的正确姿势 ifadai 关注 2017.06.16 16:22* 字数 318 阅读 3637评论 1喜欢 6 Permis ...
- .net程序和管理员权限的一些事
1.对某个方法设置管理员权限运行(未考证)(假的,必须以管理员权限启动,不然报错) [PrincipalPermission(SecurityAction.Demand, Role = @" ...
随机推荐
- Oracledb_exporter 获取表大小信息的简单方法
Oracledb_exporter 获取表大小信息的简单方法 背景 用我儿子的现状作为背景: 我爱学习, 学习让我妈快乐. 下载exporter exporter 可以在github上面下载最新版本是 ...
- [转帖]jmeter之使用csv文件传递参数-05篇
csv文件格式,第一列为手机号,第二列为密码 1.右键添加一个配置元件---csv数据文件设置 2.设置csv数据提取路径 3.引用数据 4.设置线程循环运行两次,然后发送请求 看到结果就执行了两次, ...
- [转帖]Springboot容器化镜像设置堆内存大小
参考资料:Best Practices: Java Memory Arguments for Containers - DZone Java 有三种方式设置最大堆内存大小: 1. -Xmx 2. -X ...
- [转帖]【JVM】堆内存与栈内存详解
堆和栈的定义 java把内存分成栈内存和堆内存. (1)栈内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配. 当在一段代码块中定义一个变量时,java就在栈中为这个变量分 ...
- [转帖]011 Linux 打包与解压 tar
https://my.oschina.net/u/3113381/blog/5429977 01 压缩.打包命令有哪些? Linux 上有着各种压缩.打包的工具:tar.gzip.zip.7z,而 t ...
- ElasticSearch集群灾难:别放弃,也许能再抢救一下 | 京东云技术团队
1 前言 Elasticsearch作为一个分布式搜索引擎,自身是高可用的:但也架不住一些特殊情况的发生,如: 集群超过半数的master节点丢失,ES的节点无法形成一个集群,进而导致集群不可用: ...
- clickhouse 优化实践,万级别QPS数据毫秒写入和亿级别数据秒级返回 | 京东云技术团队
1.背景 魔笛活动平台目前在采集每个活动的用户行为数据并进行查询,解决线上问题定位慢,响应不及时的问题,提升客诉的解决效率.目前每天采集的数据量5000万+,一个月的数据总量15亿+,总数据量40亿+ ...
- js中数组reduce的使用原来这么简单
reduce 的学习方法 array.reduce(callback(prev, currentValue, index, arr), initialValue) //简写就是下面这样的 arr.re ...
- 【K哥爬虫普法】房产数据刑吗?爬虫多年没踩过缝纫机,劝你找找自己原因!
我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识,知 ...
- 基于密码学的身份混淆系统 -- idmix
简介 Hyperledger Fabric的Idemix是一个基于密码学的身份混淆系统,它提供了一种在区块链网络中实现用户隐私的方法.Idemix的主要特性是它的零知识证明系统,这是一种允许用户证明他 ...