我有一个自助服务终端应用,必须禁用任务管理器,以防止用户关闭程序。
但是有些用户需要TaskManager来关闭挂起程序。
任何帮助都会被挪用。
但是,我确信在Windows中有一个函数可以防止关闭程序的进程,就像一次尝试杀死 rundll.exe 进程一样。如果我可以使用DllImport
任何人都可以帮忙解决问题吗?
一个黑客?
一个功能?
任何其他解决方案?
修改
至少如果没有办法阻止进程被关闭,我需要一种方法将其隐藏在任务管理器中出现的进程列表中。
编辑2: 到目前为止我找不到解决方案
答案 0 :(得分:6)
如果您可以在管理上下文中访问进程ID,则一种方法是拒绝对最终用户的进程的PROCESS_TERMINATE权限。默认情况下,终止进程(通过任务管理器或其他上下文)授予所有者,但可以明确拒绝。拒绝时,终止进程将要求所有者手动更改ACL,然后终止进程。如果用户既不是管理员也不是流程的所有者,他将无法强行终止该流程(例如,通过任务管理器),尽管该流程将被允许正常退出。
以下代码为Everyone组成员的PID processid
进程显式拒绝ACE。
#include "Aclapi.h"
#include "Sddl.h"
DWORD RestrictTerminateOnProcessId(DWORD processid)
{
PACL dacl = NULL, newdacl = NULL;
HANDLE ph = NULL;
PSECURITY_DESCRIPTOR* desc = NULL;
PSID everyonesid = NULL;
ph = OpenProcess(WRITE_DAC | READ_CONTROL, false, processid);
if (!ph) goto cleanup;
if (ERROR_SUCCESS != GetSecurityInfo(ph,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&dacl,
NULL,
desc)) goto cleanup;
SID_IDENTIFIER_AUTHORITY WorldAuth = SECURITY_WORLD_SID_AUTHORITY;
if (!AllocateAndInitializeSid(
&WorldAuth,1,SECURITY_WORLD_RID,
0,0,0,0,0,0,0,&everyonesid)) goto cleanup;
// begin copy dacl
_ACL_SIZE_INFORMATION si;
GetAclInformation(dacl,
&si,
sizeof(si),
AclSizeInformation);
DWORD dwNewAclSize = si.AclBytesInUse +
(2*sizeof(ACCESS_DENIED_ACE)) + (2*GetLengthSid(everyonesid)) -
(2*sizeof(DWORD));
newdacl = (PACL)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwNewAclSize);
if (newdacl == NULL) goto cleanup;
if (!InitializeAcl(newdacl, dwNewAclSize, ACL_REVISION_DS))
goto cleanup;
if (!AddAccessDeniedAce(newdacl,
ACL_REVISION_DS,
PROCESS_TERMINATE,
everyonesid)) goto cleanup;
for (int i = 0; i < si.AceCount; i++)
{
LPVOID pace = NULL;
if (!GetAce(dacl, i, &pace)) goto cleanup;
if (!AddAce(newdacl, ACL_REVISION_DS,
MAXDWORD, pace, ((PACE_HEADER)pace)->AceSize))
goto cleanup;
}
// end copy dacl
if (!SetSecurityInfo(ph,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
newdacl,
NULL)) goto cleanup;
SetLastError(0);
cleanup:
DWORD ret = GetLastError();
if (desc) LocalFree(desc);
if (newdacl) HeapFree(GetProcessHeap(), 0, (LPVOID)newdacl);
if (ph) CloseHandle(ph);
if (everyonesid) FreeSid(everyonesid);
return !ret;
}
答案 1 :(得分:5)
您可以创建在启动时运行的服务。然后monitors when the user logs进入并启动您的程序。从那里你有两个选择:
如果您必须允许用户拥有管理权限(并因此可以终止您的服务),请务必注册您的服务以便SCM restarts it automatically。
除此之外的任何事情都需要一些内核黑客攻击,正如mdm所说,或潜入rootkit领域。我建议你避免使用。
如果您仍然运行Windows XP而不是系统服务,则可以注册Winlogon notification package。它们基本上是不可杀戮的,因为它们在winlogon.exe的环境中运行,这就是它们从Vista及以上版本removed的原因。
答案 2 :(得分:5)
这样做的正确方法是:
为Kiosk应用程序创建用户。让我们说KioskUser 创建在计算机中执行操作的其他用户。让我们说User1 他们中的任何人都不应该是管理员。他们不需要是管理员吗?他们当然可以享有特权。
您将像往常一样使用User1帐户。 然后,您将Kiosk应用程序作为KioskUser运行。 (使用runas命令) - 将应用程序添加到会话中并使其可见(有关此更多信息,请参阅参数)
当User1进入并且Kiosk应用程序从KioskUser运行时,User1无法终止该进程。
我不建议“黑客”系统,也不建议改变注册表上的内容。 此外,您可以将Kiosk应用程序设为服务,并在Kiosk用户下运行。
答案 3 :(得分:2)
听起来你不能阻止一个进程被杀 - 请参阅this question,特别是link posted to an explanation。
但是,您可以阻止用户从任务栏打开任务管理器(右键单击 - >打开任务管理器),按Ctrl-Shift-Esc,或者在命令提示符下键入taskman
使用以下注册表项:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableTaskMgr
将其设置为1会禁用任务管理器,0会再次启用它。
在命令提示符下,将其禁用如下:
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 1 /f
您可以使用此命令重命名:
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 0 /f
您还需要找到一种方法来防止用户在注册表中写入此密钥 - 尽管在我的Windows 7 64位计算机上,我必须先打开管理命令提示符才能更改密钥。< / p>
修改强>
根据评论中的建议,您可以拦截低级系统调用以更改报告的进程列表。 This answer躲过它,你基本上必须编写一个内核模式rootkit - 可能是作为设备驱动程序实现的。由于在Vista及更高版本中进行内核更改,这可能仅适用于Windows XP及更低版本。然而,可以这样做,我的一个朋友为他的BSc最后一年论文创建了这个原型。
您还必须考虑其他查询流程的方法 - IIRC NtQuerySystemInformation
并不是枚举流程的唯一方法。
答案 4 :(得分:1)
使用某些rootkit /驱动程序保护您的Kiosk应用程序是不可能的......虽然您在此上下文中需要使用的方法是“类似恶意软件”,但要注意......
这里http://blogs.msdn.com/b/oldnewthing/archive/2004/02/16/73780.aspx你可以在一方面看到为什么这是一项不太可能的任务,另一方面你需要防范的几种可能性......这将是:
拒绝PROCESS_TERMINATE
拒绝PROCESS_CREATE_THREAD
拒绝PROCESS_VM_WRITE
拒绝PROCESS_SUSPEND_RESUME
再加上任何防御措施,你都可以对抗调试器 - 另一个非常棘手的业务。
答案 5 :(得分:1)
很抱歉不发布此评论(声誉不足)。 我正在使用drfs解决方案,但它似乎通过使用GetSecurityInfo的方式导致内存泄漏。我改变了代码并摆脱了这样的内存泄漏:
声明:
console
初始化:
PSECURITY_DESCRIPTOR desc = NULL;
清理:
desc = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED, sizeof(PSECURITY_DESCRIPTOR));
呼叫:
if (desc) GlobalFree(desc);
我还在这个问题上发现了这篇文章:http://i1.blogs.msdn.com/b/oldnewthing/archive/2012/12/12/10376639.aspx
答案 6 :(得分:0)
虽然您无法阻止授权用户终止您的进程,但您可以阻止用户拥有杀死进程所需的权限。也就是说,本地管理员将始终拥有杀死任何进程的权限。您希望阻止任何用户或非管理员关闭您的应用程序吗?如果是前者,只需在专用用户帐户下运行该流程就足以完成这一操作。