1、利用ToolHelp API 首先创建一个系统快照,然后通过对系统快照的访问完成进程的枚举获取系统快照使用CreateToolhelp32Snapshot 函数 函数原型声明如下:
将dwFlags设置为TH32CS_SNAPPROCESS用于获取进程快照。函数调用成功后会返回一个快照的句柄,便可以使用Process32First、Process32Next进行枚举了 函数原型声明如下:
下面是相关代码:
用此方法可以在进程ID和进程名称间进行转换,即通过进程名称获得进程ID,通过进程ID获取进程名称。
2、通过psapi.dll提供的函数 通过psapi.dll提供的EnumProcesses、EnumProcessModules实现 函数原型声明如下:
此方法由于需要进行OpenProcess操作,所以需要一定的权限,当权限不够时,有些进程将不能被打开。 下面给出提升权限的相关代码:
3、通过ntdll.dll提供的Native API 使用Native API 中的ZwQuerySystemInformation的SystemProcessesAndThreadsInformation系统调用枚举进程由于该函数没有被导出,所以首先定义要使用到的结构和常量
然后动态加载ntdll.dll,获得函数的地址。便可以进行进程的枚举
4、通过进程打开的句柄来枚举进程
一直在使用一个小工具叫unlocker。知道它是用关闭句柄的方法来删除文件的,但是自己也没有怎么研究过这东西。传说中更厉害的方法是直接向磁盘写0 和Xcb大法,最近准备好好研究这些删除方法。那么就从句柄开始吧。这里我只做枚举句柄的工作,因为关闭句柄就是把ZwDuplicateObject 的Options 这个参数赋值为DUPLICATE_CLOSE_SOURCE 。这里还要感谢一下sudami和NetRoc同学。。。O(∩_∩)O哈哈~
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[MAX_PATH] = _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[1024], cbNeeded, cProcesses; unsigned int i; if(!EnumProcesses(aProcesses,sizeof(aProcesses),&cbNeeded)) return; cProcesses = cbNeeded/sizeof(DWORD); for(i=0;i<cProcesses;i++) PrintProcessNameAndID(aProcesses[i]); getchar(); }
此方法由于需要进行OpenProcess操作,所以需要一定的权限,当权限不够时,有些进程将不能被打开。 下面给出提升权限的相关代码:
void RaisePrivilege() { HANDLE hToken; TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if ( OpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken ) ) { if ( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &tp.Privileges[0].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[6]; FILETIME ftCreateTime; FILETIME ftUserTime; FILETIME ftKernelTime; UNICODE_STRING ProcessName; DWORD BasePriority; DWORD ProcessId; DWORD InheritedFromProcessId; DWORD HandleCount; DWORD Reserved2[2]; DWORD VmCounters; DWORD dCommitCharge; PVOID ThreadInfos[1]; }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[6]; FILETIME ftCreateTime; FILETIME ftUserTime; FILETIME ftKernelTime; UNICODE_STRING ProcessName; DWORD BasePriority; DWORD ProcessId; DWORD InheritedFromProcessId; DWORD HandleCount; DWORD Reserved2[2]; DWORD VmCounters; DWORD dCommitCharge; PVOID ThreadInfos[1]; }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[1]; }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[i].ProcessId ) { OldPID = pInfo->Information[i].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[3]; 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[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; 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[IRP_MJ_CREATE] = pDriverObj->MajorFunction[IRP_MJ_CLOSE] = pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = 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[i]; 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); }
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2302
- 用户1336
- 访客10970171
每日一句
Qingming Festival invites us to honor ancestors with quiet reflection and respect.
清明节邀请我们以静思与敬意祭奠祖先。
清明节邀请我们以静思与敬意祭奠祖先。
新会员