フィルタドライバではIoGetCurrentProcess
を呼び出してPEPROCESS
構造体を呼び出し、PsGetProcessImageFileName
を呼び出してファイル名を取得することができます。フィルタドライバで現在のプロセスイメージファイルのフルネームを取得する方法は?
私の質問はどうすれば入手できますかプロセスイメージファイルの名前は?
フィルタドライバではIoGetCurrentProcess
を呼び出してPEPROCESS
構造体を呼び出し、PsGetProcessImageFileName
を呼び出してファイル名を取得することができます。フィルタドライバで現在のプロセスイメージファイルのフルネームを取得する方法は?
私の質問はどうすれば入手できますかプロセスイメージファイルの名前は?
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);
}
// ...
}
コードがプロセスハンドルをリークしているようです。 –
リークが修正されました。 – codeDom
いいえ、ハンドルを閉じないコードパスがあります。バッファの割り当てが失敗したとき、または 'ZwQueryInformationProcess'の最初の呼び出しがSTATUS_INFO_LENGTH_MISMATCHとは異なる何かを返すとき。他のいくつかのエラーパスは正しく処理されていないようです( 'PslookupProcessByProcessId'が失敗した場合、' MmGetSystemRoutineAddress'が 'ZwQueryInformationProcess'のアドレスを取得できなかった場合)。その中にはNTSTATUSコードのエラーが返されるものもありますが、著者の意図よりも幸運なことだと思います。 –
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)
)は、このようなテーブルを構築して管理するときに非常に便利です。
関連リンクhttp://www.osronline.com/showThread.cfm?link=109252 –
これはwinapiの質問のようです。もしそうなら、確かにそれはC++の質問ではなく(確かに言語固有のタグがあれば)、Cの質問ではありません。タグを適切に更新してください。 –
フィルタドライバ私はC++で記述することはできません。 – codeDom