2012-05-21 40 views
5

Vorrei arrestare un programma in esecuzione di mia scelta (ad esempio, notepad ++, becrypt, word) per scopi di test del software.forzare l'arresto di qualsiasi processo in esecuzione

So come BSOD, so come causare un programma che scrivo in crash, so come terminare il processo - ma come arrestare un processo esistente non lo faccio!

aiuto?

+0

Se si tratta di un programma che è possibile collegare un debugger, è possibile uscire dal debugger senza scollegarlo: ciò causerà il blocco dell'applicazione. –

risposta

1

È possibile utilizzare DLL injection technique per iniettare il codice in un altro processo. Quindi nel tuo codice iniettato fai qualcosa di semplice come abort() o divisione per zero.

4

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.

1

è necessario un meccanismo in due fasi:

  1. iniettare il processo di crash (utilizzando una libreria di iniezione, utilizzando Detours, utilizzando un impianto di Hook, ecc ..). Ciò che scegli dipende dal tempo e dalle conoscenze che hai e da altre precondizioni (come credenziali, protezione anti-iniezione, dimensioni del footprint che vuoi lasciare ..)
  2. esegue un'operazione non valida nel processo iniettato (come int 2Eh, dividere per null, ecc.)
Problemi correlati