Bene, utilizzare CreateRemoteThread
su un processo remoto e richiamare qualcosa [1] che arresta il processo in modo affidabile. Non sono sicuro se le protezioni da CreateRemoteThread
siano in contrasto con i puntatori nulli, ma potresti passare un indirizzo nella pagina nulla e far eseguire il processo remoto.
[1] puntatore nullo o l'accesso pagina null, divisione per zero, invocando un'istruzione privilegiata, int3
...
Esempio:
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
BOOL setCurrentPrivilege(BOOL bEnable, LPCTSTR lpszPrivilege)
{
HANDLE hToken = 0;
if(::OpenThreadToken(::GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)
|| ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
TOKEN_PRIVILEGES tp;
LUID luid;
if(!::LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
::CloseHandle(hToken);
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;
// Enable the privilege or disable all privileges.
if(!::AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL)
)
{
CloseHandle(hToken);
return FALSE;
}
::CloseHandle(hToken);
}
return TRUE;
}
int killProcess(DWORD processID)
{
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if(hProcess)
{
if(!setCurrentPrivilege(TRUE, SE_DEBUG_NAME))
{
_tprintf(TEXT("Could not enable debug privilege\n"));
}
HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)1, NULL, 0, NULL);
if(hThread)
{
::CloseHandle(hThread);
}
else
{
_tprintf(TEXT("Error: %d\n"), GetLastError());
::CloseHandle(hProcess);
return 1;
}
::CloseHandle(hProcess);
}
return 0;
}
int __cdecl _tmain(int argc, _TCHAR *argv[])
{
killProcess(3016);
}
Naturalmente si vorrà regola il PID nella chiamata a killProcess
. Compilato con WNET DDK e testato su Server 2003 R2.
L'essenza qui è che diciamo al processo remoto di eseguire il codice all'indirizzo 0x1 ((LPTHREAD_START_ROUTINE)1
), che si trova all'interno della pagina nulla ma non un puntatore nullo (nel caso in cui ci siano controlli contro questo). La crudezza attorno alla funzione, in particolare setCurrentPrivilege
viene utilizzata per ottenere i privilegi di debug completi in modo che possiamo compiere la nostra azione malvagia.
Se si tratta di un programma che è possibile collegare un debugger, è possibile uscire dal debugger senza scollegarlo: ciò causerà il blocco dell'applicazione. –