内核中通过进程PID获取进程的全部路径
目录
一丶简介我们遇到的Dos路径.如果想转化为NT路径(也就是 C:xxxx)类似的格式 二丶原理1.原理1.使用** ZwOpenProcess ** 通过进程PID获取HANDLE 2.代码实现.typedef NTSTATUS(*PfnZwQueryInformationProcess) ( __in HANDLE ProcessHandle,__in PROCESSINFOCLASS ProcessInformationClass,__out_bcount(ProcessInformationLength) PVOID ProcessInformation,__in ULONG ProcessInformationLength,__out_opt PULONG ReturnLength ); PfnZwQueryInformationProcess ZwQueryInformationProcess; //初始化未公开的导出函数 NTSTATUS InitGloableFunction() { UNICODE_STRING UtrZwQueryInformationProcessName = RTL_CONSTANT_STRING(L"ZwQueryInformationProcess"); ZwQueryInformationProcess = (PfnZwQueryInformationProcess)MmGetSystemRoutineAddress(&UtrZwQueryInformationProcessName); return STATUS_SUCCESS; } NTSTATUS GetDosPathByProcessId(IN ULONG pid,OUT PANSI_STRING pAnsiNtPath) { /* 1.根据PID获取进程句柄 2.使用ZwQueryInformationProcess 传入HANDLE 使用27号功能获取路径 */ HANDLE hProcess = 0; CLIENT_ID cid; OBJECT_ATTRIBUTES obj; NTSTATUS ntStatus; ULONG RetLength = 0; PVOID pBuffer = NULL; HANDLE hFile; IO_STATUS_BLOCK iostu; PVOID FileObject = NULL; PFILE_OBJECT pMyFileObject = NULL; UNICODE_STRING DosName; UNICODE_STRING FunllPath; if (ZwQueryInformationProcess == NULL) return STATUS_UNSUCCESSFUL; cid.UniqueProcess =(HANDLE)pid; cid.UniqueThread = 0; InitializeObjectAttributes(&obj,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,0); ntStatus = ZwOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&obj,&cid); if (!NT_SUCCESS(ntStatus)) return STATUS_UNSUCCESSFUL; //使用27 号功能遍历 ntStatus = ZwQueryInformationProcess(hProcess,ProcessImageFileName,NULL,&RetLength); if (STATUS_INFO_LENGTH_MISMATCH != ntStatus) return STATUS_UNSUCCESSFUL; //申请内存继续获取. pBuffer = ExAllocatePoolWithTag(PagedPool,RetLength,'niBI'); if (NULL == pBuffer) return STATUS_UNSUCCESSFUL; //重新调用获取. ntStatus = ZwQueryInformationProcess(hProcess,pBuffer,&RetLength); if (!NT_SUCCESS(ntStatus)) { if (NULL != pBuffer) { ExFreePoolWithTag(pBuffer,'niBI'); } return STATUS_UNSUCCESSFUL; } //开始转化路径 InitializeObjectAttributes(&obj,OBJ_KERNEL_HANDLE,0); ntStatus = ZwOpenFile( &hFile,GENERIC_READ,&iostu,FILE_SHARE_READ| FILE_SHARE_WRITE,0); if (!NT_SUCCESS(ntStatus)) { if (NULL != pBuffer) { ExFreePoolWithTag(pBuffer,'niBI'); } ZwClose(hFile); return STATUS_UNSUCCESSFUL; } //获得文件对象 ntStatus = ObReferenceObjectByHandle( hFile,GENERIC_ALL,*IoFileObjectType,KernelMode,&FileObject,NULL); if (!NT_SUCCESS(ntStatus)) { if (NULL != pBuffer) { ExFreePoolWithTag(pBuffer,'niBI'); } ntStatus = ObDereferenceObject(FileObject); ZwClose(hFile); return STATUS_UNSUCCESSFUL; } pMyFileObject = (PFILE_OBJECT)FileObject; if (NULL == pMyFileObject) { if (NULL != pBuffer) { ExFreePoolWithTag(pBuffer,'niBI'); } ntStatus = ObDereferenceObject(FileObject); ZwClose(hFile); return STATUS_UNSUCCESSFUL; } //通过 RtlVolumeDeviceToDosName 获取Dos路径 也即是C: D: 等盘符 RtlVolumeDeviceToDosName(pMyFileObject->DeviceObject,&DosName); //获得路径直接直接拼接即可. FunllPath.MaximumLength = pMyFileObject->FileName.MaximumLength + DosName.MaximumLength; FunllPath.Length = pMyFileObject->FileName.Length + DosName.Length; FunllPath.Buffer = ExAllocatePoolWithTag(NonPagedPool,FunllPath.MaximumLength,0); //拼接路径 RtlCopyUnicodeString(&FunllPath,&DosName);//得到C: RtlAppendUnicodeStringToString(&FunllPath,&pMyFileObject->FileName);//得到C:xxx路径,转为Asii RtlUnicodeStringToAnsiString(pAnsiNtPath,&FunllPath,TRUE); //RtlFreeAnsiString 要释放空间. ExFreePool(FunllPath.Buffer); //因为传出自动为其分配了内存所以这个进行谁放 if (NULL != pBuffer) { ExFreePoolWithTag(pBuffer,'niBI'); } ntStatus = ObDereferenceObject(FileObject); ZwClose(hFile); return STATUS_SUCCESS; } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj,PUNICODE_STRING pRegPath) { ANSI_STRING AnsiNtPath; pDriverObj->DriverUnload = DriverUnLoad; InitGloableFunction(); KdBreakPoint(); GetDosPathByProcessId(3356,&AnsiNtPath); return STATUS_SUCCESS; } 以下为调试的时候的代码截图. 2.使用RtlVolumeDeviceToDosName 得到盘符 3.拼接路径为UNICODE_STRING类型 4.为传入的ANSI_STRING 分配空间转换.得到ANSI_STRING路径. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |