windows驱动里通过进程ID获得进程名和所属用户

 在windows驱动中,通过 进程ID,可以获得进程完整路径和进程名,

也可以获得进程所属的用户名。

以下代码是整理出来完成这些功能的 两个实现函数。


// By fanxiushu 2013-07-02

///获得进程名

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;
}


你可能感兴趣的:(C++,驱动开发)