【问题标题】:Process.GetProcessById enabling "debug mode"Process.GetProcessById 启用“调试模式”
【发布时间】:2015-02-11 11:40:07
【问题描述】:

在我的一个 C# 应用程序 (.NET 2) 中,我使用了一个非托管模式库 (C),它调用了一些 OpenProcess()s。我最近添加了一些使用 Process.GetProcessById() 的 C# 代码。在此更改之后,OpenProcess() 开始成功,即使应用于使它们失败的 PID。经过一番调查,我发现Process.GetProcessById() 隐式将SeDebugPrivilege 设置为应用程序(注意:当前用户具有管理员权限)。由于在我的特定应用程序中这种行为是不可取的,我最终通过调用 Process.LeavDebugMode() 恢复了正常权限。

由于我找不到任何描述,我对我的程序的正确性有些担心。调用Process.LeavDebugMode() 来“调整”Process.GetProcessById() 的工作是否正确?简而言之,我的 Process.GetProcessById() 是否按预期工作(例如,由 MSDN 记录)或者我观察到的行为是否隐藏了我的应用程序中的一些细微错误?

我的操作系统是用于嵌入式系统的 Windows 7 SP1 64 位。

编辑:更多信息:进程以 32 位模式运行(即它运行 32 位版本的 .NET 引擎)。另外,我添加了这个“.config”文件以确保使用的 .NET 版本是 2:

<configuration>
 <startup>
  <supportedRuntime version="v2.0.50727"/>
 </startup>
</configuration>

EDIT2:更多实验:编写了一个普通的 C#/WindowsForm 应用程序(感谢 MS 向导 ;-)),添加了两个按钮,一个用于调用 Process.GetProcessById(),一个用于调用Process.LeaveDebugMode()。以下是相关代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;


namespace testproc
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Process proc = Process.GetProcessById(Process.GetCurrentProcess().Id);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Process.LeaveDebugMode();
        }
    }
}

启动应用程序(在 VS 之外),然后我启动了进程资源管理器。它证实了奇怪的“功能”:

  • 应用程序刚刚启动:SeDebugPrivilege 已禁用
  • 按下按钮 1:SeDebugPrivilege 已启用!
  • 按下按钮 2:SeDebugPrivilege 再次禁用
  • 按下按钮 1:SeDebugPrivilege 仍处于禁用状态(嗯...)

所以,我只能确认我的断言(至少对于Process.GetProcessById() 的第一次调用)。有什么想法吗?

【问题讨论】:

    标签: c# .net winapi process


    【解决方案1】:

    看起来像 .NET 中的一个错误,尽管在有人可以重现之前,它有可能只是您机器上的一些怪异。

    无论哪种方式,调用 LeaveDebugMode() 来解决该问题应该是无害的。它所做的只是禁用特权,将线程返回到正常状态。 (文档没有说,但大概在调试权限已被禁用时调用 LeaveDebugMode() 根本没有任何作用;这就是底层 API 的行为方式。)

    【讨论】:

    • 我设法在完全不同的系统(但都是 W7-64)上重现了它:一个嵌入式版本和一个普通的 W7 Professional。两者都安装了反恶意软件,但不一样:W7-embedded 上的 Avira 和 W7-professional 上的 MCafee。没有安装其他特别的东西。顺便说一句,出于向后兼容性的原因,我仍然必须使用 VS2005(但我并不重要)。
    • 我不能在这里复制它,但我不是 C# 专家,所以我可能做错了什么。
    • 我仍在调查这个问题。答案对我来说是令人满意的,因为我想确定 LeaveDebugMode 是一个合理的解决方法,但我想发现这个奇怪事物的实际来源。也许一些 MS 修补程序?我会尽快在完全不同的机器上尝试我的测试用例,我不敢相信这样的错误就在身边,而且没有人注意到它。我的环境一定有问题。也许……
    • 如果是bug,那就是微妙的;要注意到这一点,您必须测试某些东西 不起作用 - 实际上,当您尝试打开不应访问的进程时确实会出错。程序员主要测试确实工作的东西。 (我认为他们称之为负面特征。)如果它没有引起注意,我不会太惊讶,特别是如果它只发生在极少数情况下。
    • 好点:确实很难(也不是很有趣)注意到应用程序有一些额外的、意想不到的权限。如果我学到一些有趣的东西,我会告诉你的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    • 2020-09-29
    • 2011-09-21
    • 2020-09-10
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多