你好,
我寫了一隻模擬 ntsd -c q 功能的console程式,經過測式後可以殺多數殺不掉的程序。但若要應用在一般的程式上,真的需要做許多壓力測式來了解所有的資源是否都清的很乾淨。即使是使用ntsd也是一樣的道理。必竟這不是正規的terminate process的方式…至少未save的data是一定會lost的。我目前沒有大量的thread測式環境,還請若有機會test,可以把結果分享一下:
程式的原理很簡單,是利用debug 的api把process attach上來,然後用一個debug自然的機制…即debugger程式離開時,被debug的process也會被terminate。至於這個自然的機制是如何處理…目前我也還不很清楚。
由上面的原理來看,我們需要先編一個獨立的exe檔來attach process,然後結束自己…我用c的語法寫(非cpp)
#include
#include
#include
BOOL tokenUp(void); //提昇權限至debug模式
void tokenRestore(void); //回復原來的權限
DWORD main(int argc, char* argv[])
{
DWORD dwId, dwError;
if (argc != 2)
{
fprintf(stderr,"Usage: %s ProcessId\n", argv[0]);
return 1;
}
dwId = _atoi64(argv[1]);
if(!DebugActiveProcess(dwId))
{
dwError = GetLastError();
if(dwError != ERROR_ACCESS_DENIED)
{
printf("Error Num = %u",dwError);
return dwError;
}
if(tokenUp())
{
// try to attach again
if(!DebugActiveProcess(dwId))
{
dwError = GetLastError();
printf("Error Num = %u",dwError);
return dwError;
}
tokenRestore();
return 0;
}
dwError = GetLastError();
printf("Error Num = %u",dwError);
return dwError;
}
return 0;
}
//---------------------------------------------------------------------------
static TOKEN_PRIVILEGES Priv, PrivOld;
static DWORD cbPriv = sizeof(PrivOld);
static DWORD dwError;
static HANDLE hToken;
BOOL tokenUp(void)
{
// get current thread token
if (!OpenThreadToken(GetCurrentThread(),
TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,
FALSE, &hToken))
{
if (GetLastError() != ERROR_NO_TOKEN)
return FALSE;
// revert to the process token, if not impersonating
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,
&hToken))
return FALSE;
}
// _ASSERTE(ANYSIZE_ARRAY > 0);
Priv.PrivilegeCount = 1;
Priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME,
&Priv.Privileges[0].Luid);
// try to enable the privilege
if (!AdjustTokenPrivileges(hToken, FALSE, &Priv, sizeof(Priv),
&PrivOld, &cbPriv))
{
dwError = GetLastError();
CloseHandle(hToken);
return SetLastError(dwError), FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
// the SE_DEBUG_NAME privilege is not in the caller's token
CloseHandle(hToken);
return SetLastError(ERROR_ACCESS_DENIED), FALSE;
}
return TRUE;
}
void tokenRestore(void)
{
// restore original privilege state
AdjustTokenPrivileges(hToken, FALSE, &PrivOld, sizeof(PrivOld),
NULL, NULL);
CloseHandle(hToken);
}
這個console程式可以單獨使用,我compile為killp.exe ,就可以在dos box下執行 killp 1234 (假設pid是1234)。
若要應用在你的form ap上,則需要使用create process的api來執行它…如下:
STARTUPINFO si;
PROCESS_INFORMATION pi;
String cmd;
cmd = "killp " Edit1->Text;
LPTSTR szCmdline=cmd.c_str();
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line)
szCmdline, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
)
{
ShowMessage(String().sprintf("CreateProcess failed (%d).\n", GetLastError()));
return;
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
蕭沖 qs.xiao@gmail.com
===================引 用 文 章===================
各位先進您們好:
引用:
問:怎麼才能關掉一個用任務管理器關不了的進程?我前段時間發現我的機子裏多了一個進程,只要開機就在,我用任務管理器卻怎麼關也關不了
答1:殺進程很容易,隨便找個工具都行。比如IceSword。關鍵是找到這個進程的啟動方式,不然下次重啟它又出來了。順便教大家一招狠的。其實用Windows自帶的工具就能殺大部分進程:
c:\>ntsd -c q -p PID
但我想在我的程式內有這樣的功能,不知要怎麼寫,我要強制讓自己的程式快速關閉,且關得乾淨。