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 = @" ...
随机推荐
- [转帖]被误解的CPU利用率、超线程、动态调频 —— CPU 性能之迷 Part 1
https://blog.mygraphql.com/zh/notes/hw/hyper-threading/ 引 性能测试.压力测试.业务系统性能容量评估.这 3 件事,可以认为是大部分程序员/软件 ...
- [转帖]Java 容器化的历史坑(史坑) - 资源限制篇
原文:https://blog.mygraphql.com/zh/posts/cloud/containerize/java-containerize/java-containerize-resour ...
- [转帖]Rust在windows下安装以后cargo build Error: linker `link.exe` not found
D:\rust\runoob-greeting\greeting>cargo build error: linker `link.exe` not found | = note: 系统找不到指定 ...
- [转帖]linux下/proc/sysrq-trigger详解
/proc/sysrq-trigger详解 这是一组"魔术组合键",只要内核没有被完全锁住,不管内核在做什么事情,使用这些组合键能即时打印出内核的信息. 使用SysRq组合键是了解 ...
- GS7 备份恢复之后客户端登录报错的解决方法:COM 类工厂中 CLISID 为 xxxx的组建失败, 原因是出现了一下错误 8000401a
1. 最近需要创建一个用户的数据库应用信息, 备份恢复之后发现有时候一些环境无法使用. COM 类工厂中 CLISID 为 xxxx的组建失败, 原因是出现了一下错误 8000401a 错误图片为 2 ...
- vue新一轮的面试题
参考的连接: https://juejin.cn/post/6844903876231954446 1. 在vue中watch和created哪个先执行?为什么? 在wacth监控数据时,设置imme ...
- vue render函数的简单使用(1)
1.render函数的介绍 在vue中我们经常使用HTML模板语法来组建页面. 除此之外,使用还可以使用render函数来创建页面. 因为vue是虚拟DOM,拿到template模板时也要转译成VNo ...
- 小程序跳转到h5页面无法获取参数
在小程序中,遇见这样一个需求: 小程序(携带token)跳转到H5页面: 在H5端取token;将token作为参数: 然后返回来的信息, 这里遇见一个问题,在created中无法获取地址栏的参数: ...
- 【VictoriaMetrics源码阅读】vm中仿照RoaringBitmap的实现:uint64set
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu 公众号:一本正经的瞎扯 正文 VictoriaMetrics中使用uint64类型来表示一个Me ...
- .NetCore开发人员首选框架---Bridge(Abp-VNext + Vue3)
bridge系统是基于Abp-VNext+Vue3开发的一套前后端分离的通用权限管理系统,不论是单体服务,还是微服务都可在此基础上自由扩展,此框架组合可以说是集成了.netcore在BS架构领域最前沿 ...