I would like to crash a running program of my choice (e.g., notepad++, becrypt, word) for software testing purposes.
I know how to BSOD, I know how to cause a program I write to crash, I know how to end process - but how to crash an existing process I do not!
any help?
Well, use CreateRemoteThread
on a remote process and invoke something [1] that crashes the process reliably. I'm not sure whether CreateRemoteThread
guards against null pointers, but you could pass an address in the null page to it and have the remote process execute that.
[1] null pointer or null page access, division by zero, invoking a privileged instruction, int3
...
Example:
#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);
}
Of course you'll want to adjust the PID in the call to killProcess
. Compiled with WNET DDK and tested on 2003 Server R2.
The gist here is that we tell the remote process to execute code at address 0x1 ((LPTHREAD_START_ROUTINE)1
), which is inside the null page but not a null pointer (in case there are checks against that). The crud around the function, in particular setCurrentPrivilege
is used to gain full debug privileges so we can do our evil deed.
You can use DLL injection technique in order to inject your code into another process. Then in your injected code do something simple like abort() or division by zero.
A two steps mechanism is needed:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With