c++枚举系统句柄
1、利用ToolHelp API首先创建一个系统快照,然后通过对系统快照的访问完成进程的枚举获取系统快照使用CreateToolhelp32Snapshot 函数
函数原型声明如下:
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
将dwFlags设置为TH32CS_SNAPPROCESS用于获取进程快照。函数调用成功后会返回一个快照的句柄,便可以使用Process32First、Process32Next进行枚举了
函数原型声明如下:
BOOL WINAPI Process32First(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);
BOOL WINAPI Process32Next( HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
下面是相关代码:
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
void useToolHelp()
{
HANDLE procSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if ( procSnap == INVALID_HANDLE_VALUE )
{
printf( "CreateToolhelp32Snapshot failed, %d ", GetLastError() );
return;
}
/**/
PROCESSENTRY32 procEntry = { 0 };
procEntry.dwSize = sizeof(PROCESSENTRY32);
BOOL bRet = Process32First( procSnap, &procEntry );
while ( bRet )
{
wprintf( L"PID: %d (%s) ", procEntry.th32ProcessID, procEntry.szExeFile );
bRet = Process32Next( procSnap, &procEntry );
}
CloseHandle( procSnap );
}
void main()
{
useToolHelp();
getchar();
}
用此方法可以在进程ID和进程名称间进行转换,即通过进程名称获得进程ID,通过进程ID获取进程名称。
2、通过psapi.dll提供的函数
通过psapi.dll提供的EnumProcesses、EnumProcessModules实现
函数原型声明如下:
BOOL EnumProcesses( DWORD* pProcessIds, DWORD cb, DWORD* pBytesReturned);BOOL EnumProcessModules( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded);
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "psapi.h"
#pragma comment(lib,"psapi.lib")
void PrintProcessNameAndID(DWORD processID)
{
TCHAR szProcessName = _T("<unknown>");
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID);
//Process name.
if(NULL!=hProcess)
{
HMODULE hMod;
DWORD cbNeeded;
if(EnumProcessModules(hProcess,&hMod,sizeof(hMod), &cbNeeded))
{
GetModuleBaseName(hProcess,hMod,szProcessName,sizeof(szProcessName)/sizeof(TCHAR));
}
}
wprintf(_T("PID: %d (%s) "),processID,szProcessName);
CloseHandle(hProcess);
}
void main( )
{
DWORD aProcesses, cbNeeded, cProcesses;
unsigned int i;
if(!EnumProcesses(aProcesses,sizeof(aProcesses),&cbNeeded))
return;
cProcesses = cbNeeded/sizeof(DWORD);
for(i=0;i<cProcesses;i++)
PrintProcessNameAndID(aProcesses);
getchar();
}
此方法由于需要进行OpenProcess操作,所以需要一定的权限,当权限不够时,有些进程将不能被打开。
下面给出提升权限的相关代码:
void RaisePrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges.Attributes = SE_PRIVILEGE_ENABLED;
if ( OpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken ) )
{
if ( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &tp.Privileges.Luid ) )
{
AdjustTokenPrivileges( hToken, FALSE, &tp, NULL, NULL, 0 );
}
}
if ( hToken )
CloseHandle( hToken );
}
3、通过ntdll.dll提供的Native API
使用Native API 中的ZwQuerySystemInformation的SystemProcessesAndThreadsInformation系统调用枚举进程由于该函数没有被导出,所以首先定义要使用到的结构和常量
typedef DWORD (WINAPI *ZWQUERYSYSTEMINFORMATION)(DWORD, PVOID, DWORD, PDWORD);
typedef struct _SYSTEM_PROCESS_INFORMATION
{
DWORD NextEntryDelta;
DWORD ThreadCount;
DWORD Reserved1;
FILETIME ftCreateTime;
FILETIME ftUserTime;
FILETIME ftKernelTime;
UNICODE_STRING ProcessName;
DWORD BasePriority;
DWORD ProcessId;
DWORD InheritedFromProcessId;
DWORD HandleCount;
DWORD Reserved2;
DWORD VmCounters;
DWORD dCommitCharge;
PVOID ThreadInfos;
}SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
#define SystemProcessesAndThreadsInformation 5
然后动态加载ntdll.dll,获得函数的地址。便可以进行进程的枚举
#include <windows.h>
#include <ntsecapi.h>
#include <stdio.h>
typedef DWORD (WINAPI * ZWQUERYSYSTEMINFORMATION)( DWORD, PVOID, DWORD, PDWORD );
typedef struct _SYSTEM_PROCESS_INFORMATION
{
DWORD NextEntryDelta;
DWORD ThreadCount;
DWORD Reserved1;
FILETIME ftCreateTime;
FILETIME ftUserTime;
FILETIME ftKernelTime;
UNICODE_STRING ProcessName;
DWORD BasePriority;
DWORD ProcessId;
DWORD InheritedFromProcessId;
DWORD HandleCount;
DWORD Reserved2;
DWORD VmCounters;
DWORD dCommitCharge;
PVOID ThreadInfos;
}SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
#define SystemProcessesAndThreadsInformation 5
void main()
{
HMODULE hNtDll = GetModuleHandle( L"ntdll.dll" );
if ( !hNtDll )
return;
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION) GetProcAddress( hNtDll, "ZwQuerySystemInformation" );
ULONG cbBuffer = 0x10000;
LPVOID pBuffer = NULL;
pBuffer = malloc( cbBuffer );
if ( pBuffer == NULL )
return;
ZwQuerySystemInformation( SystemProcessesAndThreadsInformation, pBuffer, cbBuffer, NULL );
PSYSTEM_PROCESS_INFORMATION pInfo = (PSYSTEM_PROCESS_INFORMATION) pBuffer;
for (;; )
{
wprintf( L"PID: %d (%ls) ", pInfo->ProcessId, pInfo->ProcessName.Buffer );
if ( pInfo->NextEntryDelta == 0 )
break;
pInfo = (PSYSTEM_PROCESS_INFORMATION) ( ( (PUCHAR) pInfo) + pInfo->NextEntryDelta);
}
free( pBuffer );
getchar();
}
4、通过进程打开的句柄来枚举进程
#include <windows.h>
#include <ntsecapi.h>
#include <ntstatus.h>
#include <stdio.h>
typedef NTSTATUS (WINAPI * ZWQUERYSYSTEMINFORMATION)( DWORD, PVOID, DWORD, PDWORD );
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
}SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_INFORMATION Information;
}SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
#define SystemHandleInformation 0x10 /* 16 */
void main()
{
HMODULE hNtDll = LoadLibrary( L"ntdll.dll" );
if ( !hNtDll )
return;
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION) GetProcAddress( hNtDll, "ZwQuerySystemInformation" );
ULONG cbBuffer = 0x4000;
LPVOID pBuffer = NULL;
NTSTATUS s;
do
{
pBuffer = malloc( cbBuffer );
if ( pBuffer == NULL )
return;
memset( pBuffer, 0, cbBuffer );
s = ZwQuerySystemInformation( SystemHandleInformation, pBuffer, cbBuffer, NULL );
if ( s == STATUS_INFO_LENGTH_MISMATCH )
{
free( pBuffer );
cbBuffer = cbBuffer * 2;
}
}
while ( s == STATUS_INFO_LENGTH_MISMATCH );
PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX) pBuffer;
ULONG OldPID = 0;
for ( DWORD i = 0; i < pInfo->NumberOfHandles; i++ )
{
if ( OldPID != pInfo->Information.ProcessId )
{
OldPID = pInfo->Information.ProcessId;
wprintf( L"PID: %d ", OldPID );
}
}
free( pBuffer );
FreeLibrary( hNtDll );
getchar();
}
一直在使用一个小工具叫unlocker。知道它是用关闭句柄的方法来删除文件的,但是自己也没有怎么研究过这东西。传说中更厉害的方法是直接向磁盘写0 和Xcb大法,最近准备好好研究这些删除方法。那么就从句柄开始吧。这里我只做枚举句柄的工作,因为关闭句柄就是把ZwDuplicateObject 的Options 这个参数赋值为DUPLICATE_CLOSE_SOURCE 。这里还要感谢一下sudami和NetRoc同学。。。O(∩_∩)O哈哈~
#include <ntddk.h>
#define AYA_DEVICE L"\\Device\\EnumHandle"
#define AYA_LINK L"\\DosDevices\\EnumHandle"
#define SystemHandleInformation 16
#define OB_TYPE_PROCESS 5
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectAllInformation,
ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
typedef struct _OBJECT_BASIC_INFORMATION {
ULONG Attributes;
ACCESS_MASK DesiredAccess;
ULONG HandleCount;
ULONG ReferenceCount;
ULONG PagedPoolUsage;
ULONG NonPagedPoolUsage;
ULONG Reserved;
ULONG NameInformationLength;
ULONG TypeInformationLength;
ULONG SecurityDescriptorLength;
LARGE_INTEGER CreationTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
typedef struct _KOBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
WCHAR NameBuffer[];
} KOBJECT_NAME_INFORMATION, *PKOBJECT_NAME_INFORMATION;
typedef struct _OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
ULONG TotalNumberOfHandles;
ULONG TotalNumberOfObjects;
WCHAR Unused1;
ULONG HighWaterNumberOfHandles;
ULONG HighWaterNumberOfObjects;
WCHAR Unused2;
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;
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryObject(
IN HANDLE Handle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG ObjectInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwDuplicateObject(
IN HANDLE SourceProcessHandle,
IN HANDLE SourceHandle,
IN HANDLE TargetProcessHandle OPTIONAL,
OUT PHANDLE TargetHandle OPTIONAL,
IN ACCESS_MASK DesiredAccess,
IN ULONG HandleAttributes,
IN ULONG Options
);
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
);
NTSTATUS NTAPI AYA_EnumHandle();
void AYA_Unload( IN PDRIVER_OBJECT pDriverObj )
{
UNICODE_STRING Temp;
RtlInitUnicodeString( &Temp, AYA_LINK );
IoDeleteSymbolicLink( &Temp );
IoDeleteDevice( pDriverObj->DeviceObject );
}
NTSTATUS AYA_Dispatch( IN PDEVICE_OBJECT pDeviceObj, IN PIRP pIrp )
{
NTSTATUS ns = STATUS_SUCCESS;
PIO_STACK_LOCATION stIrp;
stIrp = IoGetCurrentIrpStackLocation( pIrp );
switch ( stIrp->MajorFunction )
{
case IRP_MJ_CREATE:
break;
case IRP_MJ_CLOSE:
break;
case IRP_MJ_DEVICE_CONTROL:
break;
default:
pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
}
ns = pIrp->IoStatus.Status;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return(ns);
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ns = STATUS_SUCCESS;
UNICODE_STRING AYA;
UNICODE_STRING AYAL;
PDEVICE_OBJECT pDevice;
ns = AYA_EnumHandle();
RtlInitUnicodeString( &AYA, AYA_DEVICE );
ns = IoCreateDevice( pDriverObj, 0, &AYA, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevice );
RtlInitUnicodeString( &AYAL, AYA_LINK );
ns = IoCreateSymbolicLink( &AYAL, &AYA );
pDriverObj->MajorFunction =
pDriverObj->MajorFunction =
pDriverObj->MajorFunction = AYA_Dispatch;
pDriverObj->DriverUnload = AYA_Unload;
return(ns);
}
NTSTATUS AYA_EnumHandle()
{
NTSTATUS ns = STATUS_SUCCESS;
ULONG ulSize;
PVOID pSysBuffer;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo;
SYSTEM_HANDLE_TABLE_ENTRY_INFO pSysHandleTEI;
OBJECT_BASIC_INFORMATION BasicInfo;
PKOBJECT_NAME_INFORMATION pNameInfo;
POBJECT_TYPE_INFORMATION pTypeInfo;
OBJECT_ATTRIBUTES oa;
ULONG ulProcessID;
HANDLE hProcess;
HANDLE hHandle;
HANDLE hDupObj;
CLIENT_ID cid;
ULONG i;
ulSize = 100;
do
{
pSysBuffer = ExAllocatePoolWithTag( PagedPool, ulSize, 'A0' );
ns = ZwQuerySystemInformation( SystemHandleInformation, pSysBuffer, ulSize, NULL );
ulSize *= 2;
if ( !NT_SUCCESS( ns ) )
{
ExFreePool( pSysBuffer );
}
}
while ( !NT_SUCCESS( ns ) );
pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION) pSysBuffer;
for ( i = 0; i < pSysHandleInfo->NumberOfHandles; i++ )
{
pSysHandleTEI = pSysHandleInfo->Handles;
if ( pSysHandleTEI.ObjectTypeIndex != OB_TYPE_PROCESS )
{
continue;
}
ulProcessID = (ULONG) pSysHandleTEI.UniqueProcessId;
cid.UniqueProcess = (HANDLE) ulProcessID;
cid.UniqueThread = (HANDLE) 0;
hHandle = (HANDLE) pSysHandleTEI.HandleValue;
InitializeObjectAttributes( &oa, NULL, 0, NULL, NULL );
ns = ZwOpenProcess( &hProcess, PROCESS_DUP_HANDLE, &oa, &cid );
if ( !NT_SUCCESS( ns ) )
{
KdPrint( ("ZwOpenProcess : Fail ") );
break;
}
ns = ZwDuplicateObject( hProcess, hHandle, NtCurrentProcess(), &hDupObj, \
PROCESS_ALL_ACCESS, 0, DUPLICATE_SAME_ACCESS );
if ( !NT_SUCCESS( ns ) )
{
KdPrint( ("ZwDuplicateObject : Fail ") );
break;
}
ZwQueryObject( hDupObj, ObjectBasicInformation, &BasicInfo, \
sizeof(OBJECT_BASIC_INFORMATION), NULL );
pNameInfo = ExAllocatePoolWithTag( PagedPool, BasicInfo.NameInformationLength, 'A1' );
RtlZeroMemory( pNameInfo, BasicInfo.NameInformationLength );
ZwQueryObject( hDupObj, ObjectNameInformation, pNameInfo, \
BasicInfo.NameInformationLength, NULL );
pTypeInfo = ExAllocatePoolWithTag( PagedPool, BasicInfo.TypeInformationLength, 'A2' );
RtlZeroMemory( pTypeInfo, BasicInfo.TypeInformationLength );
ZwQueryObject( hDupObj, ObjectTypeInformation, pTypeInfo, \
BasicInfo.TypeInformationLength, NULL );
KdPrint( ("NAME:%wZ\t\t\tTYPE:%wZ\n", &(pNameInfo->Name), &(pTypeInfo->TypeName) ) );
ExFreePool( pNameInfo );
ExFreePool( pTypeInfo );
}
ZwClose( hDupObj );
ZwClose( hProcess );
ZwClose( hHandle );
ExFreePool( pSysBuffer );
if ( !NT_SUCCESS( ns ) )
{
return(STATUS_UNSUCCESSFUL);
}
return(ns);
}
页:
[1]