2012-05-21 13 views
5

Chciałbym zawiesić uruchomiony program z mojego wyboru (np. Notepad ++, becrypt, word) do celów testowania oprogramowania.wymuszanie jakiegokolwiek działającego procesu powodującego awarię:

Wiem, jak BSOD, wiem, jak spowodować, że program, który napiszę, zawiesił się, wiem, jak zakończyć proces - ale jak zawiesić istniejący proces, którego nie mam!

jakiej pomocy?

+0

Jeśli to program, do którego możesz dołączyć debugger, możesz wyjść z debuggera bez odłączania - to spowoduje awarię aplikacji –

Odpowiedz

1

Możesz użyć DLL injection technique, aby wprowadzić swój kod w inny proces. Następnie w swoim wstrzykniętym kodzie wykonaj coś prostego, na przykład abort() lub dzielenie przez zero.

4

Cóż, użyj CreateRemoteThread na zdalnym procesie i wywołaj coś [1], które niezawodnie wywala proces. Nie jestem pewien, czy CreateRemoteThread chroni przed wskaźnikami zerowymi, ale można przekazać do niego adres w pustej stronie i wykonać zdalny proces.

[1] NULL lub null, dostęp strona, dzielenie przez zero, powołując się doskonałą dyspozycję, int3 ...


Przykład:

#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); 
} 

Oczywiście będziemy chcieli dostosuj PID w wywołaniu do killProcess. Skompilowany z WNET DDK i przetestowany na 2003 Server R2.

Istotą jest to, że mówimy procesowi zdalnemu, aby wykonywał kod pod adresem 0x1 ((LPTHREAD_START_ROUTINE)1), który znajduje się wewnątrz pustej strony, ale nie jest wskaźnikiem zerowym (w przypadku, gdy istnieją kontrole przeciwko temu). Crud wokół funkcji, w szczególności setCurrentPrivilege jest używany do uzyskania pełnych przywilejów debugowania, abyśmy mogli wykonać nasz zły uczynek.

1

Mechanizm dwa kroki są potrzebne:

  1. wstrzyknąć proces awarię (z wykorzystaniem biblioteki wtrysku, używając Detours, wykorzystując instalację hak, itp ..). To, co wybierzesz, zależy od czasu i posiadanej wiedzy oraz innych warunków wstępnych (takich jak dane uwierzytelniające, ochrona przed wtryskiem, rozmiar odcisku palca, który chcesz opuścić).
  2. wykonać nieprawidłową operację w procesie wstrzyknięcia (np. Int 2Eh, dzielenie przez null, itd.)
Powiązane problemy