通过进程PID获得进程名和所属用户
以下代码是整理出来完成这些功能的 两个实现函数。
///获得进程名 NTSTATUS get_process_name(int pid, PWCHAR* out_fullpath, PWCHAR* out_name ) { typedef NTSTATUS (*xxQUERY_INFO_PROCESS) ( __in HANDLE ProcessHandle, __in PROCESSINFOCLASS ProcessInformationClass, __out_bcount(ProcessInformationLength) PVOID ProcessInformation, __in ULONG ProcessInformationLength, __out_opt PULONG ReturnLength ); static xxQUERY_INFO_PROCESS ZwQueryInformationProcess = NULL ; NTSTATUS status = STATUS_UNSUCCESSFUL; ULONG returnedLength; ULONG bufferLength; PVOID buffer; PUNICODE_STRING imageName; HANDLE handle; *out_name = NULL; *out_fullpath = 0; if( KeGetCurrentIrql() != PASSIVE_LEVEL ){ DPT("IRQL Must PASSIVE_LEVEL.\n"); return status; } if (NULL == ZwQueryInformationProcess) { UNICODE_STRING routineName; RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess"); ZwQueryInformationProcess = (xxQUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName); if (NULL == ZwQueryInformationProcess) { DPT("Cannot resolve ZwQueryInformationProcess\n"); return status ; } } ///get process handle; OBJECT_ATTRIBUTES ObjectAttributes; CLIENT_ID clientid; InitializeObjectAttributes(&ObjectAttributes, 0 ,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); clientid.UniqueProcess = (HANDLE)pid; clientid.UniqueThread=0; status = ZwOpenProcess(&handle, PROCESS_ALL_ACCESS, &ObjectAttributes, &clientid); if( !NT_SUCCESS(status)){ return status; } // status = ZwQueryInformationProcess( handle, ProcessImageFileName, NULL, // buffer 0, // buffer size &returnedLength); if (STATUS_INFO_LENGTH_MISMATCH != status) { ZwClose(handle); return status; } bufferLength = returnedLength - sizeof(UNICODE_STRING); buffer = ExAllocatePoolWithTag(NonPagedPool, returnedLength, 'FXSD'); if (NULL == buffer) { ZwClose(handle); return STATUS_NO_MEMORY ; } __try { status = ZwQueryInformationProcess( handle, ProcessImageFileName, buffer, returnedLength, &returnedLength); if (NT_SUCCESS(status)) { imageName = (PUNICODE_STRING) buffer; USHORT len = imageName->Length; RtlMoveMemory( buffer, imageName->Buffer, imageName->Length ); RtlZeroMemory( ((PUCHAR)buffer) + len, sizeof(WCHAR) ); *out_fullpath = (PWCHAR)buffer; PWCHAR ptr = wcsrchr( (PWCHAR)buffer, L'\\'); if( ptr ){ *out_name = ptr + 1; }else{ *out_name = (PWCHAR)buffer; } ZwClose(handle); return STATUS_SUCCESS; } } __except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); DPT("get_process_name: Exception!!\n"); } ZwClose(handle); ExFreePool(buffer); return status; } ///以上是获得进程名,函数用完,需要手动释放内存 ExFreePool( out_fullpath ); / //获得进程所在用户,函数使用完,需要手动释放内存 ExFreePool( out_name); //要能成功编译,需要 包含 ntifs.h头文件和添加 ksecdd.lib 库 static NTSTATUS get_procees_user( int pid, PWCHAR* out_name ) { NTSTATUS status = STATUS_UNSUCCESSFUL; *out_name = NULL; PEPROCESS pProcess = NULL; PACCESS_TOKEN Token; LUID luid; PSecurityUserData userInformation = NULL; PWCHAR name = NULL; /// if( KeGetCurrentIrql() != PASSIVE_LEVEL ){ DPT("IRQL Must PASSIVE_LEVEL.\n"); return status; } status = PsLookupProcessByProcessId((HANDLE)pid, &pProcess ); if(!NT_SUCCESS(status)){ DPT("Not Find PID=%d\n", pid); return status; } Token = PsReferencePrimaryToken(pProcess); status = SeQueryAuthenticationIdToken(Token, &luid); if( !NT_SUCCESS(status)){ DPT("SeQueryAuthenticationIdToken Error<%u>\n",status ); goto E; } status = GetSecurityUserInfo(&luid, UNDERSTANDS_LONG_NAMES, &userInformation); if(!NT_SUCCESS(status) ){ DPT("GetSecurityUserInfo Error<%u>\n",status ); goto E; } name = (PWCHAR)ExAllocatePool(NonPagedPool, userInformation->UserName.Length +sizeof(WCHAR) ); if(!name){ status = STATUS_NO_MEMORY; goto E; } RtlZeroMemory( name, userInformation->UserName.Length +sizeof(WCHAR) ); RtlCopyMemory( name, userInformation->UserName.Buffer, userInformation->UserName.Length ); *out_name = name ; E: ObDereferenceObject( pProcess ); ObDereferenceObject( Token ); if( userInformation ) LsaFreeReturnBuffer( userInformation ); return status; }