c#如何实现进程防杀
如题~~~
[解决办法]
好像有点难度,多数的进程都是可以杀死的
[解决办法]
防杀可能比较难,写个Windows服务看着进程,杀掉后立马启动可以不?
[解决办法]
病毒?
[解决办法]
像绿坝那样,做两个进程互相保护
[解决办法]
搞个后台进程保护这个进程
[解决办法]
[解决办法]
进程防杀
如何在XP/2000下使指定进程不在任务管理器中显示或显示但不能被强制终止(要有源码)
当前位置:首页 > Delphi开发 > Windows API > 如何在XP/2000下使指定进程不在任务管理器中显示或显示但不能被强制终止(要有源码)
kingroad 发表于 2005-3-7 19:05:00
这个问题我已查了多遍,但没有找到妥善的解答,希望高手指教,分不够可加,谢谢!
问题如下:在XP/2000下使指定进程不在任务管理器中显示,或显示但不能被强制终止。
kingroad 发表于 2005-3-7 19:06:26
有一篇相关的帖子供参考:
在WINDOWS操作系统下,当我们无法结束或者不知道怎样结束一个程序的时候,或者是懒得去找“退出”按钮的时候,通常会按“CTRL+ALT +DEL”呼出任务管理器,找到想结束的程序,点一下“结束任务”就了事了,呵呵,虽然有点粗鲁,但大多数情况下都很有效,不是吗?
设想一下,如果有这么一种软件,它所要做的工作就是对某个使用者在某台电脑上的活动作一定的限制,而又不能被使用者通过“结束任务”这种方式轻易地解除限制,那该怎么做?无非有这么三种方法:1.屏蔽“CTRL+ALT+DEL”这个热键的组合;2.让程序不出现在任务管理器的列表之中;3.让任务管理器无法杀掉这个任务。对于第一种方法,这样未免也太残酷了,用惯了“结束任务”这种方法的人会很不习惯的;对于第二种方法,在WINDOWS 9X 下可以很轻易地使用注册服务进程的方法实现,但是对于WINDOWS NT架构的操作系统没有这个方法了,进程很难藏身,虽然仍然可以实现隐藏,但实现机制较为复杂;对于第三种方法,实现起来比较简单,我的作品:IPGate 网址过滤器 就是采用的这种方式防杀的,接下来我就来介绍这种方法。
任务管理器的“结束任务”实际上就是强制终止进程,它所使用的杀手锏是一个叫做TerminateProcess()的Win32 API函数,我们来看看它的定义:
BOOL TerminateProcess(
HANDLE hProcess, // 将被结束进程的句柄
UINT uExitCode // 指定进程的退出码
);
看到这里,是不是觉得不必往下看都知道接下来要做什么:Hook TerminateProcess()函数,每次 TerminateProcess()被调用的时候先判断企图结束的进程是否是我的进程,如果是的话就简单地返回一个错误码就可以了。真的是这么简单吗?先提出一个问题,如何根据hProcess判断它是否是我的进程的句柄?答案是:在我的进程当中先获得我的进程的句柄,然后通过进程间通讯机制传递给钩子函数,与hProcess进行比较不就行了?错!因为句柄是一个进程相关的值,不同进程中得到的我的进程的句柄的值在进程间进行比较是无意义的。
怎么办?我们来考察一下我的hProcess它是如何得到的。一个进程只有它的进程ID是独一无二的,操作系统通过进程ID来标识一个进程,当某个程序要对这个进程进行访问的话,它首先得用OpenProcess这个函数并传入要访问的进程ID来获得进程的句柄,来看看它的参数:
HANDLE OpenProcess(
DWORD dwDesiredAccess, // 希望获得的访问权限
BOOL bInheritHandle, // 指明是否希望所获得的句柄可以继承
DWORD dwProcessId // 要访问的进程ID
);
脉络渐渐显现:在调用TerminateProcess()之前,必先调用OpenProcess(),而OpenProcess()的参数表中的 dwProcessId是在系统范围内唯一确定的。得出结论:要Hook的函数不是TerminateProcess()而是OpenProcess (),在每次调用OpenProcess()的时候,我们先检查dwProcessId是否为我的进程的ID(利用进程间通讯机制),如果是的话就简单地返回一个错误码就可以了,任务管理器拿不到我的进程的句柄,它如何结束我的进程呢?
至此,疑团全部揭开了。由Hook TerminateProcess()到Hook OpenProcess()的这个过程,体现了一个逆向思维的思想。其实我当初钻进了TerminateProcess()的死胡同里半天出也不来,但最终还是蹦出了灵感的火花,注意力转移到了 OpenProcess()上面,实现了进程防杀。喜悦之余,将这心得体会拿出来与大家分享。
2 如何在XP/2000下使指定进程不在任务管理器中显示或显示但不能被强
dear12399 发表于 2005-3-7 20:08:50
一般是通过隐藏进程的方式来实现
kingroad 发表于 2005-3-8 20:30:45
dear12399:
应该是进程隐藏,不过请详细一些好吗?
jfyes 发表于 2005-3-8 20:46:44
win2000/xp/2003下不能关闭程序的方法
只针对2000以上系统,9X的就别问我了,4年没搞了:)
一般有4种方法:
1)DLL挂靠方法
程序改写为DLL结构,挂靠Explorer.exe上运行
好处:没进程实体,普通进程查看无效
缺点:可以通过代码叫Explorer.exe Unload你的Dll,呵呵,还有Explorer出错时,会重新启用,那个时候需要重新挂靠你的DLL
改进:用Debug权限挂靠WinLogon.exe,哈哈,安全系数就高很多,WinLogon死了,你也就死机了
LYSoft主页的http://ly.activepower.net/projects/No Ctrl+Alt+Del.rar是DLL挂靠方法的例子,修改就可用
2)API Hook方法
关闭程序的实质是什么?TerminateProcess的API!
只要你的Application.Title:=‘’就不会出现在任务管理器的第一页
第二页会出现的,但不怕,我Hook了TerminateProcess就可以保证安全了
TerminateProcess可以Hook?可以,但Hook了没用,Handle是未知的
因此实质上要Hook的是OpenProcess,只要是我的进程就拒绝打开
好处:不怕你见的到,你就是关不了我
缺点:CMD下的命令行方法Hook不到
改进:能够Hook系统服务就一定可以,可惜难度大,需要编写驱动
LYSoft主页的http://ly.activepower.net/projects/API Hook.rar是API Hook方法的例子,修改就可用
3)NT内核修改方法
修改NT系统内核对象PsLoadedModuleList上的ActiveProcessLink链表就可以在系统上“失踪”了,但实现这个功能需要驱动支持,没驱动的方法只能适合XP/2003,因为Nt5.1以上的ZwSystemDebugControl API才能支持内核访问
好处:你怎么都见不到进程的
缺点:难度过大,用内核工具仍然可以看见的,很多RootKit木马就用这个方法的
改进:几乎是终极大法,没什么别的好方法了。
LYSoft主页的http://ly.activepower.net/projects/NTLowLevel.exe是演示程序
关键代码如下
function HideProcess: boolean;
label Err;
var
EProcess : DWord;
hPM, FLink, BLink: Cardinal;
begin
Result := false;
EProcess := GetCurrentEProcess;
if EProcess < 1 then Exit;
if not ReadVirtualMemory(EProcess+$88, @FLink, 4) then Exit;
if not ReadVirtualMemory(EProcess+$8C, @BLink, 4) then Exit;
if not WriteVirtualMemory(FLink+4, @BLink, 4) then Exit;
if not WriteVirtualMemory(BLink, @FLink, 4) then Exit;
Result := true;
end;
不要问为什么了,你需要NTDDK的知识才能明白的:)
4)远程线程方法
没有实体的存在,没进程,没DLL,只有代码
把代码直接注入进程空间VirtualAllocEx,用CreateRemoteThread运行,
好处:没可见的实体,隐蔽性最强
缺点:适合于简单代码,复杂的难以保证其可靠性和稳定性,病毒的最爱
改进:不需要什么了
这个没演示了,呵呵:)
注入某个进程空间,要涉及到API定位等一系列病毒式操作,在对方的身体运行呀
简单的代码可以,复杂的功能就很不适合,一般的程序根本就不适合,所以除非写病毒,否则不建议用这样的方法,因为连调试都变得很难
另外如果进程本身是系统权限,而用户是只是管理员权限的话,按照操作系统设计的原理,还是无法结束进程。
[解决办法]
你想用C#写的话,建议放弃此想法。
[解决办法]
using System;using System.Collections.Generic;using System.Text;using System.Diagnostics;namespace ConsoleApplication2{ class Program { static void Main() { Test a = new Test(); Console.ReadKey();//保证这个进程不结束 } } class Test { private Process myProcess = new Process(); public Test() { myProcess.StartInfo.FileName = "iexplore.exe"; myProcess.EnableRaisingEvents = true; myProcess.Exited += new EventHandler(Process_Exited); myProcess.Start(); } public void Process_Exited(object sender, EventArgs e) { try { myProcess.WaitForExit(); Console.WriteLine("结束时间: {0}\r\n" + "终止代码: {1}\r\n", myProcess.ExitTime, myProcess.ExitCode); } finally { myProcess.Refresh(); myProcess.StartInfo.FileName = "iexplore.exe"; myProcess.EnableRaisingEvents = true; myProcess.Exited += new EventHandler(Process_Exited); myProcess.Start(); } } }}