6楼用bcb写的程序可视化增强了不少,但是我认为这个程序运行在Windows 9x/Me上应该没有问题但是在Windows NT以上的系统上由于Windows NT的安全机制,不能杀掉某些进程,OpenProcess函数会返回ERROR_ACCESS_DENIED的错误,如一些以服务启动的进程。在Windows NT中要杀掉以服务启动的进程要用到一楼的方法。
4楼说的未文档化ZwQuerySystemInformation函数是一个NTDLL.DLL中导出的函数,通过他可以存取大量系统信息,可以用它列出当前运行的系统进程。这个函数用在Windows NT(<5.0)中,在杀进程的时候用它也只是为获取一些要杀进程的信息,最后杀的时候还是用到一楼说的方法的。所以要是win2000或是xp的话不如用ToolHelp32 API。未文档化的函数并不是有多神秘,而且也在发展变化,不是很稳定,在各版本的windows中兼容性不是很好。
我也试着写了一个类似的程序,vc6.0编译,运行在win2k或xp系统上。
复制内容到剪贴板
代码:
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
void ValidateArgs(int argc, char **argv); //Parse the command line arguments
void usage(); //Print usage information and exit
void CheckOS(); //Check the OS we are running on
void EnumPS(); //Enumerate processes
BOOL KillPS(DWORD id); //kill process
BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege); //need this function to set privilege
int main(int argc,char *argv[])
{
CheckOS();
ValidateArgs(argc,argv);
return 0;
}
void ValidateArgs(int argc, char **argv)
{
int i;
if(argc!=1){
for(i = 1; i < argc; i++)
{
if ((argv[i][0] == '-'))
{
switch (tolower(argv[i][1]))
{
case 'e':
EnumPS();
break;
case 'k':
KillPS(atol(&argv[i+1][0]));
break;
default:
usage();
break;
}
}
}
}else{ usage(); }
}
void usage()
{
printf("\n");
printf("\t\t--- code by 恶猫[E.S.T] ---\n");
printf("\t\t--- E-mail: [email]EvilC4t@126.com[/email] ---\n");
printf("\t\t--- HomePage: [url]www.eviloctal.com/forum[/url] ---\n");
printf("\t\t--- Date: 04-17-2005 ---\n\n");
printf("usage: ps.exe <OPTION>\n\n");
printf(" -e enumerate processes\n");
printf(" -k:ProcessID the ProcessID you want to kill\n");
ExitProcess(1);
}
void CheckOS()
{
OSVERSIONINFO osinfo;
osinfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osinfo))
{
printf("Unable to get OS version!\n");
ExitProcess(1);
}
if (osinfo.dwPlatformId & VER_PLATFORM_WIN32_NT)
{
if (osinfo.dwMajorVersion<5)
{
printf("ToolHelp API isn't support on NT versions prior to Windows 2000!\n");
ExitProcess(1);
}
}
}
void EnumPS()
{
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (!hSnapshot)
{
printf("Unable to create snapshot!\n");
return;
}
PROCESSENTRY32 pe;
ULONG count=0;
pe.dwSize=sizeof(PROCESSENTRY32);
BOOL retval=Process32First(hSnapshot,&pe);
while(retval)
{
count++;
printf("[%d] %s\n",pe.th32ProcessID,pe.szExeFile);
retval=Process32Next(hSnapshot,&pe);
}
CloseHandle(hSnapshot);
printf("%lu processes enumerated\n",count);
}
BOOL KillPS(DWORD id)
{
HANDLE hProcess=NULL,hProcessToken=NULL;
BOOL IsKilled=FALSE,bRet=FALSE;
__try
{
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken))
{
printf("\nOpen Current Process Token failed:%d",GetLastError());
__leave;
}
if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE))
{
__leave;
}
if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,id))==NULL)
{
printf("\nOpen Process %d failed:%d",id,GetLastError());
__leave;
}
if(!TerminateProcess(hProcess,1))
{
printf("\nTerminateProcess failed:%d",GetLastError());
__leave;
}else{ printf("process %d has been killed",id); }
IsKilled=TRUE;
}
__finally
{
if(hProcessToken!=NULL) CloseHandle(hProcessToken);
if(hProcess!=NULL) CloseHandle(hProcess);
}
return(IsKilled);
}
BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
{
printf("\nLookupPrivilegeValue error:%d", GetLastError() );
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);
if (GetLastError() != ERROR_SUCCESS)
{
printf("AdjustTokenPrivileges failed: %u\n", GetLastError() );
return FALSE;
}
return TRUE;
}