【问题标题】:PYTHON | stop user killing process蟒蛇 |停止用户杀死进程
【发布时间】:2011-11-28 13:14:46
【问题描述】:

这里提到了一个很酷的功能:

Prevent user process from being killed with "End Process" from Process Explorer

有谁知道如何将此 C++ 代码翻译成 Python(或重新编辑它,以便它至少可以在 C/C++ 中编译,假设它是这样的):

static const bool ProtectProcess()
{
    HANDLE hProcess = GetCurrentProcess();
    EXPLICIT_ACCESS denyAccess = {0};
    DWORD dwAccessPermissions = GENERIC_WRITE|PROCESS_ALL_ACCESS|WRITE_DAC|DELETE|WRITE_OWNER|READ_CONTROL;
    BuildExplicitAccessWithName( &denyAccess, _T("CURRENT_USER"), dwAccessPermissions, DENY_ACCESS, NO_INHERITANCE );
    PACL pTempDacl = NULL;
    DWORD dwErr = 0;
    dwErr = SetEntriesInAcl( 1, &denyAccess, NULL, &pTempDacl );
    // check dwErr...
    dwErr = SetSecurityInfo( hProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pTempDacl, NULL );
    // check dwErr...
    LocalFree( pTempDacl );
    CloseHandle( hProcess );
    return dwErr == ERROR_SUCCESS;
}

【问题讨论】:

  • 为什么要让用户更难终止进程?
  • 编辑它以使其编译为 C++ 是什么意思。它不编译吗?看起来很容易通过 ctypes 移植到 Pythin。
  • 不胜感激上面的 ctype 示例
  • 那么,您喜欢 ctypes 示例吗?

标签: python process-management


【解决方案1】:

这是您发布的代码的相当粗略的 ctypes 翻译。它甚至似乎工作!请注意,我删除了对CloseHandle 的调用,这是完全错误的。你不应该在伪句柄上调用CloseHandle,这是GetCurrentProcess 返回的。

from ctypes import *
from ctypes.wintypes import *
from win32con import *

class TRUSTEE(Structure):
    pass

TRUSTEE._fields_ = (
    ('pMultipleTrustee', POINTER(TRUSTEE)),
    ('MultipleTrusteeOperation', c_int),
    ('TrusteeForm', c_int),
    ('TrusteeType', c_int),
    ('ptstrName', LPSTR)
)

class EXPLICIT_ACCESS(Structure):
    _fields_ = (
        ('grfAccessPermissions', DWORD),
        ('grfAccessMode', c_int),
        ('grfInheritance', DWORD),
        ('Trustee', TRUSTEE)
    )

GetCurrentProcess = windll.kernel32.GetCurrentProcess
GetCurrentProcess.restype = HANDLE
hProcess = GetCurrentProcess()

denyAccess = EXPLICIT_ACCESS()
dwAccessPermissions = DWORD(GENERIC_WRITE|PROCESS_ALL_ACCESS|WRITE_DAC|DELETE|WRITE_OWNER|READ_CONTROL);

BuildExplicitAccessWithName = windll.advapi32.BuildExplicitAccessWithNameA
BuildExplicitAccessWithName.restype = None
DENY_ACCESS = 3
NO_INHERITANCE = 0
BuildExplicitAccessWithName(byref(denyAccess), 'CURRENT_USER', dwAccessPermissions, DENY_ACCESS, NO_INHERITANCE)

SetEntriesInAcl = windll.advapi32.SetEntriesInAclA
SetEntriesInAcl.restype = DWORD
SetEntriesInAcl.argtypes = (ULONG, POINTER(EXPLICIT_ACCESS), c_voidp, POINTER(c_voidp))
pTempDacl = c_voidp()
dwErr = SetEntriesInAcl(1, byref(denyAccess), None, byref(pTempDacl));

SetSecurityInfo = windll.advapi32.SetSecurityInfo
SetSecurityInfo.restype = DWORD
SetSecurityInfo.argtypes = (HANDLE, c_int, DWORD, c_voidp, c_voidp, c_voidp, c_voidp)
SE_KERNEL_OBJECT = 6
dwErr = SetSecurityInfo(hProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, None, None, pTempDacl, None);

LocalFree = windll.kernel32.LocalFree
LocalFree.restype = c_voidp
LocalFree.argtypes = (c_voidp,)
LocalFree(pTempDacl)

【讨论】:

  • 顺便说一句,这对我来说非常适合,所以我猜它是一个可行的翻译。
  • 为什么我仍然可以关闭任务管理器上的脚本?这仍然有效吗? (Windows 7 x64,Python 3.6.6 x32)
【解决方案2】:

使用ctypes怎么样?你也可以试试pywin32。您也可以尝试使用IronPython。对于 ActivePython,有 win32api

另外,我不知道您为什么要实现这一目标的原因,这意味着可能有一些更优雅的解决方案可用。

【讨论】:

  • 它为您提供了一些指导,您可以从哪里开始寻找更多信息。您提出的问题本身并不重要,这意味着您需要进行一些重要的编码才能完全解决它:) 或者,您可以向我们提供您想要实现您正在做的事情的理由,我们可以提出一些替代解决方案。
  • 我正在编写一个用于应用程序使用监控的用户生产力模块 - 由管理员管理 - 如果它可以被用户杀死,那就不好了。我可以作为服务运行,但是所有 win32gui 项目都失败了。这似乎是一个很好/简单的选择。
  • 保持 GUI 独立并作为服务运行。这是正确的解决方案。
  • 我可以作为服务运行 - 但是诸如 win32gui.GetForegroundWindow 之类的关键函数调用失败。
  • @Ian 你需要两个进程。一种用于执行管理和日志记录,另一种用于显示 GUI。
猜你喜欢
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多