[英]Access Denied Error while trying to get the client process executable path
I am working on a WCF service that is hosted as a windows service which uses named pipes - NamedPipeServerStream (Users privilege) to establish secured connection between server and client processes. 我正在使用作为Windows服务托管的WCF服务,该服务使用命名管道-NamedPipeServerStream (用户特权)在服务器和客户端进程之间建立安全连接。 To check the authenticity of the client process, I need to verify the digital signature of the client process executable and so I am trying to get the executable path of the client by using its process id.
为了检查客户端进程的真实性,我需要验证客户端进程可执行文件的数字签名,因此我尝试使用其进程ID获取客户端的可执行文件路径。
I use Windows 7 Professional SP1 (64 bit) OS and Visual Studio 2015 Community Edition for developement. 我使用Windows 7 Professional SP1(64位)操作系统和Visual Studio 2015 Community Edition进行开发。 Both the server (windows service) and client processes (other exe) are built in Release x64 mode only.
服务器(Windows服务)和客户端进程(其他exe)都仅在Release x64模式下构建。
When some client process is connected to the server, I am trying to get the client process exe path but it is throwing "Access Denied" error in the following line of code: 当某些客户端进程连接到服务器时,我试图获取客户端进程exe路径,但在以下代码行中抛出“访问被拒绝”错误 :
return Process.GetProcessById(processId).MainModule.FileName;
Hence to resolve this issue, I had googled around and tried some other experimental trials as described below that too does not seem to work out. 因此,为了解决此问题,我在Google周围搜索并尝试了如下所述的其他一些实验性试验,但这些试验似乎也没有奏效。
Experimental Trials 实验性试验
OpenProcess(ProcessAccessFlags.PROCESS_QUERY_INFORMATION, false, processId);
OpenProcess(ProcessAccessFlags.PROCESS_QUERY_LIMITED_INFORMATION, false, processId);
However, I tried all the above methods in a sample windows console application which is working fine without any errors and the same is not working in the windows service. 但是,我在一个示例Windows控制台应用程序中尝试了所有上述方法,该应用程序运行正常,没有任何错误,并且在Windows服务中也无法正常运行。 Also I tried to convert the console application into a dll and referred it in the server to get the client process info but failed --> again Access denied
我也尝试将控制台应用程序转换为dll并在服务器中引用它以获取客户端进程信息,但失败->再次访问被拒绝
I am completely clueless about what is happening and how to resolve it. 我对正在发生的事情以及如何解决它一无所知。 Your suggestions would be really helpful.
您的建议将非常有帮助。
EDIT : Please find the code snippet for OpenProcess and the ProcessAccessFlags as below: 编辑:请找到如下所示的OpenProcess和ProcessAccessFlags的代码片段:
public static string GetProcessExecutablePath(int processId)
{
try
{
string exePath = string.Empty;
//If running on Vista or later use the new function
if (Environment.OSVersion.Version.Major >= 6)
{
return GetProcessExecutablePathAboveVista(processId);
}
return Process.GetProcessById(processId).MainModule.FileName;
}
catch (Exception ex)
{
return "Exception in GetProcessExecutablePath(): " + ex.Message + ": " + ex.InnerException;
}
}
private static string GetProcessExecutablePathAboveVista(int processId)
{
var buffer = new StringBuilder(1024);
IntPtr hprocess = NativeMethods.OpenProcess(NativeMethods.ProcessAccessFlags.PROCESS_QUERY_LIMITED_INFORMATION,
false, processId);
if (hprocess != IntPtr.Zero)
{
try
{
int size = buffer.Capacity;
if (NativeMethods.QueryFullProcessImageName(hprocess, 0, buffer, out size))
{
return buffer.ToString();
}
else
{
return "Failed in QueryFullProcessImageName(): " + Marshal.GetLastWin32Error();;
}
}
catch (Exception ex)
{
return "Exception in: " + ex.Message;
}
finally
{
NativeMethods.CloseHandle(hprocess);
}
}
else
{
return "Handle is Zero: " + Marshal.GetLastWin32Error();
}
}
NativeMethods.cs NativeMethods.cs
[Flags]
public enum ProcessAccessFlags
{
PROCESS_TERMINATE = 0x0001,
PROCESS_CREATE_THREAD = 0x0002,
PROCESS_VM_OPERATION = 0x0008,
PROCESS_VM_READ = 0x0010,
PROCESS_VM_WRITE = 0x0020,
PROCESS_DUP_HANDLE = 0x0040,
PROCESS_CREATE_PROCESS = 0x0080,
PROCESS_SET_QUOTA = 0x0100,
PROCESS_SET_INFORMATION = 0x0200,
PROCESS_QUERY_INFORMATION = 0x0400,
PROCESS_SUSPEND_RESUME = 0x0800,
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000,
SYNCHRONIZE = 0x100000,
DELETE = 0x00010000,
READ_CONTROL = 0x00020000,
WRITE_DAC = 0x00040000,
WRITE_OWNER = 0x00080000,
STANDARD_RIGHTS_REQUIRED = 0x000F0000,
PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF
}
[DllImport("Kernel32.dll", EntryPoint = "OpenProcess", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("Kernel32.dll", EntryPoint = "QueryFullProcessImageName", SetLastError = true)]
public static extern bool QueryFullProcessImageName(IntPtr hprocess, int dwFlags, StringBuilder lpExeName, out int size);
[DllImport("Kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hHandle);
For Windows starting from Vista to get process image file name by pid you may use NtQuerySystemInformation(SystemProcessInformation, ...)
to obtain array of SYSTEM_PROCESS_INFORMATION
structures for each process. 对于从Vista开始的Windows,通过pid获取进程映像文件名,可以使用
NtQuerySystemInformation(SystemProcessInformation, ...)
为每个进程获取SYSTEM_PROCESS_INFORMATION
结构的数组。 This structure has PVOID UniqueProcessId
to find pid you're looking for and UNICODE_STRING ImageName
to get image file name, see https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms724509(v=vs.85).aspx https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/process.htm 此结构具有
PVOID UniqueProcessId
以查找您要查找的pid和UNICODE_STRING ImageName
以获取图像文件名,请参阅https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms724509(v=vs.85 ).aspx https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/process.htm
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.