R3下,遍历所有进程的伪句柄表,关闭指定句柄
之所以产生这个想法,是在删除文件的时候有时会提示文件被占用了,然后让我们先关闭之后在来删除,但是我怎么知道哪个进程打开了我的文件?
于是就去网上了找了一份代码然后改了改,接着来说说是怎么实现功能的。首先我们需要遍历所有的进程,所有要找到遍历进程的代码。
//遍历进程WCHAR * szServerName = NULL;HANDLE WtsServerHandle = WTSOpenServer(szServerName);PWTS_PROCESS_INFO pWtspi;DWORD dwCount;if (!WTSEnumerateProcesses(WtsServerHandle, 0, 1, &pWtspi, &dwCount))return 0;//printf("tottal process %d", dwCount);for (DWORD i = 0; i < dwCount; i++){printf("ProcessID: %d (%ls)\n", pWtspi[i].ProcessId,pWtspi[i].pProcessName);}
现在我们能够拿到每一个进程的id,那么怎么通过进程的id拿到它的句柄信息呢?这里可以通过ZwQueryInformationProcess未文档话的函数,得到它的句柄总数,具体的参数如下
typedef NTSTATUS (WINAPI *ZWQUERYINFORMATIONPROCESS)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
其中它的第二个参数表示的是我们需要查询的内容,第三个是返回的内容,第四个是长度,最后一个不管。
通过上述函数我们能拿到当前进程的所有句柄的总数,但是需要注意的是句柄的后两位代表的是句柄的属性,也就是说,所有的句柄都是4的倍数,举一个例子,后两位不能使用了是吧,那么现在最小能使用的就是4=100二进制数,每增加一个就是增加4的倍数8=1000。拿pchunter随便看一个进程的伪句柄表,直观的看到句柄都是4的倍数。
我们现在有了每一个进程的进程句柄总数,那么只需要枚举所有的句柄不就行了吗,但是问题又来了,我们现在拿到的是伪句柄不能正常的使用,需要使用DuplicateHandle复制句柄。之后又会用到例外一个未文档话的函数ZwQueryObject,它可以查看得到当前的对象的类型和对象的名字,
typedef NTSTATUS (WINAPI *ZWQUERYOBJECT)(HANDLE OPTIONAL, OBJECT_INFORMATION_CLASS, PVOID OPTIONAL, ULONG, PULONG OPTIONAL);
最后还有一个问题,就算我们知道了每一个进程的句柄种类和名字,我们又怎么修改它呢?DuplicateHandle不仅可以复制句柄,还可以关闭源句柄。
DUPLICATE_CLOSE_SOURCE(0x00000001) Closes the source handle. This occurs regardless of any error status returned.DUPLICATE_SAME_ACCESS(0x00000002) Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.
那么最后重新整理一下思路,首先是遍历所有进程得到每一个进程的伪句柄,之后使用DuplicateHandlede复制真实的句柄,判断句柄的属性,判断句柄名字是不是我们想要的,是在干掉句柄。这里有一个小细节需要说一下就是在使用ZwQueryObject的查询句柄名字的时候会出现卡死的情况。这时我们需要创建一个新的线程来执行这个操作,避免在主线程中一直卡住。最后整理的代码如下。
#include<windows.h>
#include<stdio.h>
#include <Wtsapi32.h>
#pragma comment (lib,"Wtsapi32.lib")#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
typedef enum _POOL_TYPE {NonPagedPool,NonPagedPoolExecute,PagedPool,NonPagedPoolMustSucceed,DontUseThisType,NonPagedPoolCacheAligned,PagedPoolCacheAligned,NonPagedPoolCacheAlignedMustS,MaxPoolType,NonPagedPoolBase,NonPagedPoolBaseMustSucceed,NonPagedPoolBaseCacheAligned,NonPagedPoolBaseCacheAlignedMustS,NonPagedPoolSession,PagedPoolSession,NonPagedPoolMustSucceedSession,DontUseThisTypeSession,NonPagedPoolCacheAlignedSession,PagedPoolCacheAlignedSession,NonPagedPoolCacheAlignedMustSSession,NonPagedPoolNx,NonPagedPoolNxCacheAligned,NonPagedPoolSessionNx
} POOL_TYPE;
typedef enum _OBJECT_INFORMATION_CLASS {ObjectBasicInformation,ObjectNameInformation,ObjectTypeInformation,ObjectAllInformation,ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
typedef struct
{USHORT Length; //当前名称长度USHORT MaxLen; //缓冲区最大长度USHORT *Buffer; //Unicode 名称指针
}UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_NAME_INFORMATION {UNICODE_STRING Name;WCHAR NameBuffer[0];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
typedef struct _OBJECT_TYPE_INFORMATION {UNICODE_STRING TypeName;ULONG TotalNumberOfHandles;ULONG TotalNumberOfObjects;WCHAR Unused1[8];ULONG HighWaterNumberOfHandles;ULONG HighWaterNumberOfObjects;WCHAR Unused2[8];ACCESS_MASK InvalidAttributes;GENERIC_MAPPING GenericMapping;ACCESS_MASK ValidAttributes;BOOLEAN SecurityRequired;BOOLEAN MaintainHandleCount;USHORT MaintainTypeList;POOL_TYPE PoolType;ULONG DefaultPagedPoolCharge;ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
typedef enum _SYSTEM_INFORMATION_CLASS {SystemBasicInformation, // 0 Y NSystemProcessorInformation, // 1 Y NSystemPerformanceInformation, // 2 Y NSystemTimeOfDayInformation, // 3 Y NSystemNotImplemented1, // 4 Y NSystemProcessesAndThreadsInformation, // 5 Y NSystemCallCounts, // 6 Y NSystemConfigurationInformation, // 7 Y NSystemProcessorTimes, // 8 Y NSystemGlobalFlag, // 9 Y YSystemNotImplemented2, // 10 Y NSystemModuleInformation, // 11 Y NSystemLockInformation, // 12 Y NSystemNotImplemented3, // 13 Y NSystemNotImplemented4, // 14 Y NSystemNotImplemented5, // 15 Y NSystemHandleInformation, // 16 Y NSystemObjectInformation, // 17 Y NSystemPagefileInformation, // 18 Y NSystemInstructionEmulationCounts, // 19 Y NSystemInvalidInfoClass1, // 20SystemCacheInformation, // 21 Y YSystemPoolTagInformation, // 22 Y NSystemProcessorStatistics, // 23 Y NSystemDpcInformation, // 24 Y YSystemNotImplemented6, // 25 Y NSystemLoadImage, // 26 N YSystemUnloadImage, // 27 N YSystemTimeAdjustment, // 28 Y YSystemNotImplemented7, // 29 Y NSystemNotImplemented8, // 30 Y NSystemNotImplemented9, // 31 Y NSystemCrashDumpInformation, // 32 Y NSystemExceptionInformation, // 33 Y NSystemCrashDumpStateInformation, // 34 Y Y/NSystemKernelDebuggerInformation, // 35 Y NSystemContextSwitchInformation, // 36 Y NSystemRegistryQuotaInformation, // 37 Y YSystemLoadAndCallImage, // 38 N YSystemPrioritySeparation, // 39 N YSystemNotImplemented10, // 40 Y NSystemNotImplemented11, // 41 Y NSystemInvalidInfoClass2, // 42SystemInvalidInfoClass3, // 43SystemTimeZoneInformation, // 44 Y NSystemLookasideInformation, // 45 Y NSystemSetTimeSlipEvent, // 46 N YSystemCreateSession, // 47 N YSystemDeleteSession, // 48 N YSystemInvalidInfoClass4, // 49SystemRangeStartInformation, // 50 Y NSystemVerifierInformation, // 51 Y YSystemAddVerifier, // 52 N YSystemSessionProcessesInformation // 53 Y N
} SYSTEM_INFORMATION_CLASS;
typedef enum _PROCESSINFOCLASS
{ProcessBasicInformation = 0, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATIONProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EXProcessIoCounters, // q: IO_COUNTERSProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EXProcessTimes, // q: KERNEL_USER_TIMESProcessBasePriority, // s: KPRIORITYProcessRaisePriority, // s: ULONGProcessDebugPort, // q: HANDLEProcessExceptionPort, // s: HANDLEProcessAccessToken, // s: PROCESS_ACCESS_TOKENProcessLdtInformation, // 10ProcessLdtSize,ProcessDefaultHardErrorMode, // qs: ULONGProcessIoPortHandlers, // (kernel-mode only)ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITSProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: voidProcessUserModeIOPL,ProcessEnableAlignmentFaultFixup, // s: BOOLEANProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASSProcessWx86Information,ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATIONProcessAffinityMask, // s: KAFFINITYProcessPriorityBoost, // qs: ULONGProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EXProcessSessionInformation, // q: PROCESS_SESSION_INFORMATIONProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUNDProcessWow64Information, // q: ULONG_PTRProcessImageFileName, // q: UNICODE_STRINGProcessLUIDDeviceMapsEnabled, // q: ULONGProcessBreakOnTermination, // qs: ULONGProcessDebugObjectHandle, // 30, q: HANDLEProcessDebugFlags, // qs: ULONGProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enablesProcessIoPriority, // qs: ULONGProcessExecuteFlags, // qs: ULONGProcessResourceManagement,ProcessCookie, // q: ULONGProcessImageInformation, // q: SECTION_IMAGE_INFORMATIONProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATIONProcessPagePriority, // q: ULONGProcessInstrumentationCallback, // 40ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EXProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]ProcessImageFileNameWin32, // q: UNICODE_STRINGProcessImageFileMapping, // q: HANDLE (input)ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODEProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODEProcessGroupInformation, // q: USHORT[]ProcessTokenVirtualizationEnabled, // s: ULONGProcessConsoleHostProcess, // q: ULONG_PTRProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATIONProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATIONProcessDynamicFunctionTableInformation,ProcessHandleCheckingMode,ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATIONProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATIONMaxProcessInfoClass
}PROCESSINFOCLASS;
//上面为需要用到的结构体和枚举//定义函数指针
typedef NTSTATUS (NTAPI *ZWQUERYSYSTEMINFORMATION)( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength OPTIONAL);
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL;typedef NTSTATUS (WINAPI *ZWQUERYOBJECT)(HANDLE OPTIONAL, OBJECT_INFORMATION_CLASS, PVOID OPTIONAL, ULONG, PULONG OPTIONAL);
ZWQUERYOBJECT ZwQueryObject = NULL;typedef NTSTATUS (WINAPI *ZWQUERYINFORMATIONPROCESS)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
ZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess = NULL;//初始化未文档化函数
BOOL InitUnDocumentProc()
{HMODULE hNtdll = GetModuleHandle("Ntdll.dll");if (hNtdll == NULL) return FALSE;ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "NtQuerySystemInformation");ZwQueryObject = (ZWQUERYOBJECT)GetProcAddress(hNtdll, "NtQueryObject");ZwQueryInformationProcess = (ZWQUERYINFORMATIONPROCESS)GetProcAddress(hNtdll, "NtQueryInformationProcess");if ((ZwQuerySystemInformation == NULL) || (ZwQueryObject == NULL) || (ZwQueryInformationProcess == NULL))return FALSE;return TRUE;
}//象征性的提权,其实用处不大
BOOL EnableDebugPrivilege()
{HANDLE hToken;LUID sedebugnameValue;TOKEN_PRIVILEGES tkp;if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)){return FALSE;}if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)){CloseHandle(hToken);return FALSE;}tkp.PrivilegeCount = 1;tkp.Privileges[0].Luid = sedebugnameValue;tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)){CloseHandle(hToken);return FALSE;}return TRUE;
}//查询名字的时候会卡死
HANDLE hDuplicate = NULL;
OBJECT_NAME_INFORMATION *ObjectName;
char BufferForObjectName[1024];UINT WINAPI ZwThreadProc(PVOID lpParma){ZwQueryObject((HANDLE)hDuplicate, ObjectNameInformation, BufferForObjectName, sizeof(BufferForObjectName), NULL);ObjectName = (POBJECT_NAME_INFORMATION)BufferForObjectName;//MessageBoxA(0,0,0,0);
}int main()
{EnableDebugPrivilege();InitUnDocumentProc();NTSTATUS Status;HANDLE hSource = NULL;DWORD HandleCount;OBJECT_TYPE_INFORMATION *ObjectType;char BufferForObjectType[1024];//遍历进程WCHAR * szServerName = NULL;HANDLE WtsServerHandle = WTSOpenServer(szServerName);PWTS_PROCESS_INFO pWtspi;DWORD dwCount;if (!WTSEnumerateProcesses(WtsServerHandle, 0, 1, &pWtspi, &dwCount))return 0;//printf("tottal process %d", dwCount);/*for (DWORD i = 0; i < dwCount; i++){printf("ProcessID: %d (%ls)\n", pWtspi[i].ProcessId,pWtspi[i].pProcessName);}*/for (DWORD j = 0; j < dwCount; j++) {hSource = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_DUP_HANDLE | PROCESS_SUSPEND_RESUME, FALSE, pWtspi[j].ProcessId);if (hSource != NULL) {DWORD dwHandle;Status = ZwQueryInformationProcess(hSource, ProcessHandleCount, &HandleCount, sizeof(HandleCount), NULL);//printf("total size %d \n", HandleCount);for (DWORD i = 1; i <= HandleCount; i++) {//穷举句柄dwHandle = i * 4;//复制一个句柄对象 && 判断此句柄是否有效if (DuplicateHandle(hSource, (HANDLE)dwHandle, GetCurrentProcess(), &hDuplicate, 0, FALSE, DUPLICATE_SAME_ACCESS)) {ZeroMemory(BufferForObjectName, 1024);ZeroMemory(BufferForObjectType, 1024);//获取句柄类型Status = ZwQueryObject(hDuplicate, ObjectTypeInformation, BufferForObjectType, sizeof(BufferForObjectType), NULL);ObjectType = (OBJECT_TYPE_INFORMATION*)BufferForObjectType;if (Status == STATUS_INFO_LENGTH_MISMATCH || !NT_SUCCESS(Status))continue;//获取句柄名,会卡死,所以这里只有开一个线程//Status = ZwQueryObject((HANDLE)hDuplicate, ObjectNameInformation, BufferForObjectName, sizeof(BufferForObjectName), NULL);//ObjectName = (POBJECT_NAME_INFORMATION)BufferForObjectName;//if (Status == STATUS_INFO_LENGTH_MISMATCH || !NT_SUCCESS(Status))//continue;HANDLE hThread = CreateThread(NULL, 0, ZwThreadProc, NULL, 0, NULL);DWORD dwSatu = WaitForSingleObject(hThread, 53); // 等待,直到线程被激发if (dwSatu == WAIT_TIMEOUT) {hThread = OpenThread(THREAD_TERMINATE, FALSE, hThread);if (!TerminateThread(hThread, 0)) {CloseHandle(hThread);}CloseHandle(hThread);//MessageBoxA(0, 0, 0, 0);continue;}//关闭复制的句柄CloseHandle(hDuplicate);//printf("Type:%S\tName:%S\tHandle:%X\n", ObjectType->TypeName.Buffer,ObjectName->Name.Buffer, hDuplicate);if (ObjectName->Name.Buffer!=NULL&&!strcmp(ObjectType->TypeName.Buffer, L"File")&& wcsstr(ObjectName->Name.Buffer,L"msyh.ttc")) {//判断是不是文件类型,判断关闭文件对不对printf("pid %d \tName:%S\tHandle:%X\n", pWtspi[j].ProcessId, ObjectName->Name.Buffer, hDuplicate);//printf("pid %d \tName:%S\n", pWtspi[j].ProcessId, ObjectType->TypeName.Buffer);//关闭符合的句柄DuplicateHandle(hSource, (HANDLE)dwHandle, GetCurrentProcess(), &hDuplicate,0,FALSE,DUPLICATE_CLOSE_SOURCE);CloseHandle(hDuplicate);}}}CloseHandle(hSource);}}system("pause");return 0;
}
R3下,遍历所有进程的伪句柄表,关闭指定句柄相关推荐
- wsappx关不掉_win10系统下wsappx.exe进程占用内存大能关闭吗
有不少win10系统用户在查看任务管理器的时候,发现有一个wsappx.exe进程占用内存大,但是又不知道wsappx.exe是什么进程,可以关闭吗?针对这个问题,小编这就给大家讲解一下win10系统 ...
- Windows句柄表学习笔记 —— 句柄表全局句柄表
Windows句柄表学习笔记 -- 句柄表&全局句柄表 句柄表 实验一:在WinDbg中查看句柄表 第一步:打开一个Win32窗口程序 第二步:编译并运行以下代码 第三步:查看运行结果 第四步 ...
- EXCEL批量删除当前目录下所有工作薄的所有工作表的指定行
本代码示例用于批量删除第6, 7, 9, 10, 12, 13, 15, 16行的代码,使用这个批量删除行的代码要注意以下几点: 1)该代码只用于批量删除代码所在文件目录下(不含子目录)与 " ...
- 【超详细】遍历Windows进程模块
直奔主题 摘要 上一篇文章详细介绍了如何 遍历Windows进程.这篇文章主要是对获取的系统进程作进一步处理,依次遍历每一个进程中使用的模块!主要是用到了Module32First以及Module32 ...
- (64)句柄表,遍历所有进程的句柄表实现反调试
一.内核对象,句柄 这次课讨论的内核对象是指创建时需要指定 LPSECURITY_ATTRIBUTES 参数的对象,例如 Mutex, Thread. 调用 CreateThread 等函数会返回一个 ...
- (66)全局句柄表,遍历全局句柄表
一.回顾 前面的课程我们学习了进程的句柄表,全局句柄表和进程句柄表非常像,只有一些小区别. 这节课的课后作业我先给出来: 编写程序,通过全局句柄表PsdCidTable,遍历所有进程(包括隐藏进程). ...
- (65)如何根据句柄从二级、三级结构句柄表中找到内核对象
一.回顾 上一篇博客介绍了如何遍历一级句柄表.一级句柄表非常简单,就是一个4KB页,最多存储512个句柄表项.如果句柄数量在 512 - 1024*512 之间,句柄表就是二级结构:如果句柄数量大于 ...
- 私有句柄表(内核对象,并非用户对象),全局句柄表
文章目录 私有句柄表 1.什么是句柄(内核对象) 2.为什么要有句柄? Windows设计理念: 3.句柄表在哪? 全局句柄表 注意 私有句柄表 1.什么是句柄(内核对象) 当一个进程创建或者打开一个 ...
- Linux上怎样停止服务(jar包)、查看进程路径、关闭指定端口
场景 在linux上部署的jar包服务需要停止该服务并关闭防火墙对应的端口. 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 ...
最新文章
- 【项目实践】中英文文字检测与识别项目(CTPN+CRNN+CTC Loss原理讲解)
- PHPExcel 出现open_basedir restriction in effect的解决办法
- 一 SpringMVC源码之DispatcherServlet AbstractHanderMapping
- 11.JDK8内存模型、本地方法栈、虚拟机栈、栈帧结构(局部变量表、操作数栈、方法出口、虚拟机栈与本地方法栈的关系、寄存器、方法区、堆(Heap)、jvm中的常量池、Metaspace(元空间))
- latex表插入的位置不对_VSCode_LaTex_英文amp;中文配置
- 为什么自由职业受追捧?
- Chrome 73 稳定版正式发布,macOS 支持暗色主题
- Windows切换窗口
- Android 系统汉字转拼音 HanziToPinyin
- NetApp存储设置时间报“date: cannot set date when NTP is running.”处理
- html中版权号怎么打,网站底部版权符号怎么打出来
- 两台路由器的连接方法和无线路由桥接
- Adb文件及文件夹操作命令
- python 图像快速替换某种颜色
- Spring5春天还是配置地狱
- 【图解】九张图带你读懂大数据医疗
- 夜神模拟器 版本下载
- c语言如何不用数组排序,c语言实现数组排序.docx
- 武大计算机学院2017年博士分数线,武汉大学高等研究院2017年博士研究生综合考核录取工作通知...
- 印能捷服务器系统怎么装,Prinergy印能捷JTP全自动建立工具(32/64bit)