2016-09-06 18 views
1

フィルタドライバではIoGetCurrentProcessを呼び出してPEPROCESS構造体を呼び出し、PsGetProcessImageFileNameを呼び出してファイル名を取得することができます。フィルタドライバで現在のプロセスイメージファイルのフルネームを取得する方法は?

私の質問はどうすれば入手できますかプロセスイメージファイルの名前は?

+0

関連リンクhttp://www.osronline.com/showThread.cfm?link=109252 –

+0

これはwinapiの質問のようです。もしそうなら、確かにそれはC++の質問ではなく(確かに言語固有のタグがあれば)、Cの質問ではありません。タグを適切に更新してください。 –

+0

フィルタドライバ私はC++で記述することはできません。 – codeDom

答えて

1

here私は@Martinドラブのコードのような完全なコードを見つけ

EDIT:新しい固定コード

NTSTATUS 
GetProcessImageName(
    PEPROCESS eProcess, 
    PUNICODE_STRING* ProcessImageName 
    ) 
{ 
    NTSTATUS status = STATUS_UNSUCCESSFUL; 
    ULONG returnedLength; 
    HANDLE hProcess = NULL; 

    PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process 

    if (eProcess == NULL) 
    { 
     return STATUS_INVALID_PARAMETER_1; 
    } 

    status = ObOpenObjectByPointer(eProcess, 
     0, NULL, 0, 0, KernelMode, &hProcess); 
    if (!NT_SUCCESS(status)) 
    { 
     DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status); 
     return status; 
    } 

    if (ZwQueryInformationProcess == NULL) 
    { 
     UNICODE_STRING routineName = RTL_CONSTANT_STRING(L"ZwQueryInformationProcess"); 

     ZwQueryInformationProcess = 
      (QUERY_INFO_PROCESS)MmGetSystemRoutineAddress(&routineName); 

     if (ZwQueryInformationProcess == NULL) 
     { 
      DbgPrint("Cannot resolve ZwQueryInformationProcess\n"); 
      status = STATUS_UNSUCCESSFUL; 
      goto cleanUp; 
     } 
    } 

    /* Query the actual size of the process path */ 
    status = ZwQueryInformationProcess(hProcess, 
     ProcessImageFileName, 
     NULL, // buffer 
     0, // buffer size 
     &returnedLength); 

    if (STATUS_INFO_LENGTH_MISMATCH != status) { 
     DbgPrint("ZwQueryInformationProcess status = %x\n", status); 
     goto cleanUp; 
    } 

    *ProcessImageName = kmalloc(returnedLength); 

    if (ProcessImageName == NULL) 
    { 
     status = STATUS_INSUFFICIENT_RESOURCES; 
     goto cleanUp; 
    } 

    /* Retrieve the process path from the handle to the process */ 
    status = ZwQueryInformationProcess(hProcess, 
     ProcessImageFileName, 
     *ProcessImageName, 
     returnedLength, 
     &returnedLength); 

    if (!NT_SUCCESS(status)) kfree(*ProcessImageName); 

cleanUp: 

    ZwClose(hProcess); 

    return status; 
} 

FLT_POSTOP_CALLBACK_STATUS 
PostCreate(
    _Inout_ PFLT_CALLBACK_DATA Data, 
    _In_ PCFLT_RELATED_OBJECTS FltObjects, 
    _In_opt_ PVOID CompletionContext, 
    _In_ FLT_POST_OPERATION_FLAGS Flags 
    ) 
{ 
    PUNICODE_STRING pni = NULL; 
    NTSTATUS status = STATUS_UNSUCCESSFUL; 

    status = GetProcessImageName(IoThreadToProcess(Data->Thread), &pni); 
    if (NT_SUCCESS(status)) 
    { 
     DbgPrint("ProcessName = %ws\n", pni->Buffer); 
     kfree(pni); 
    } 
    else 
    { 
     DbgPrint("GetProcessImageName status = %x\n", status); 
    } 

    // ... 
} 
+1

コードがプロセスハンドルをリークしているようです。 –

+0

リークが修正されました。 – codeDom

+1

いいえ、ハンドルを閉じないコードパスがあります。バッファの割り当てが失敗したとき、または 'ZwQueryInformationProcess'の最初の呼び出しがSTATUS_INFO_LENGTH_MISMATCHとは異なる何かを返すとき。他のいくつかのエラーパスは正しく処理されていないようです( 'PslookupProcessByProcessId'が失敗した場合、' MmGetSystemRoutineAddress'が 'ZwQueryInformationProcess'のアドレスを取得できなかった場合)。その中にはNTSTATUSコードのエラーが返されるものもありますが、著者の意図よりも幸運なことだと思います。 –

1

ZwQueryInformationProcessを情報クラス27に使用できます。次のコードはこのルーチンを使用して、プロセスのハンドルから完全なイメージファイル名を取得します。

NTSTATUS GetProcessNameByHandle(_In_ HANDLE ProcessHandle, _Out_ PUNICODE_STRING *Name) 
{ 
    ULONG retLength = 0; 
    ULONG pniSize = 512; 
    PUNICODE_STRING pni = NULL; 
    NTSTATUS status = STATUS_UNSUCCESSFUL; 

    do { 
     pni = (PUNICODE_STRING)ExAllocatePoolWithTag(PagedPool, pniSize, POOL_TAG); 
     if (pni != NULL) { 
      status = ZwQueryInformationProcess(ProcessHandle, 27, pni, pniSize, &retLength); 
      if (!NT_SUCCESS(status)) { 
       ExFreePoolWithTag(pni, POOL_TAG); 
       pniSize *= 2; 
      } 
     } else status = STATUS_INSUFFICIENT_RESOURCES; 
    } while (status == STATUS_INFO_LENGTH_MISMATCH); 

    if (NT_SUCCESS(status)) 
     *Name = pni; 

    return status; 
} 

あなたは以下の方法により、プロセスハンドルを取得することができます。

  • ObOpenObjectByPointer、あなたはプロセスのEPROCESSアドレス(PsLookupProcessByProcessId役立つ可能性)が必要です。

  • ZwOpenProcess - 対象プロセスのPIDを知る必要があります。

ただし、このコードを使用すると、ミニフィルタの前後のコールバックを呼び出すたびに非常に時間がかかることがあります。 PIDをキーとして使用するハッシュテーブルにプロセス名をキャッシュすることで、この問題を解決します。通知ルーチン(PsSetXXXNotifyRoutine(Ex))は、このようなテーブルを構築して管理するときに非常に便利です。

関連する問題