Windows program to freeze other running programs

Why

One of the program services on my computer kept respawning despite my attempts to kill it, suspend it, or disable it via different means. I then had an idea to pause it in a way that would prevent it from annoying me, while still maintaining an impression that it was active.

How

Simply killing the process from e.g. a Task Manager won’t be effective, as it will be restarted. Suspending it via a more advanced Process Explorer won’t work reliably as something else in the system (presumably services.exe) is resuming it quite quickly.

One idea was to give the process the lowest priority possible so that it would be just starved by the OS scheduler while still being alive. Of course, this would not completely negate the harm it was doing. So then it hit me: debugging it! Attaching a debugger keep the debuggee alive, but completely under control of the debugger. This means that the process will remain frozen and unresponsive unless the debugger says so.

It was possible to attach an existing debugger such as MS VS Studio to a running process. It worked in my initial experiments. But having a full-blown IDE just hanging in background doing nothing was an overkill. So I decided to write a small program that does the initial debugger connection without actually providing the majority of usual debugger functions.

Details

The idea is to use WinAPI’s DebugActiveProcess() to connect to the victim process as a debugger. A regular debugger would then proceed with processsing debuggee events in a loop. The debuggee’s thjreads would become unfrozen and continue running at some point. In contrast, my application simply goes into an endless loop. No events are consumed and the attached application remains frozen.

Killing the debugger process kills the debuggee as well. This is WinAPI’s default behavior.

This logic is stored in stallattach.cpp.

Dealing with Permissions

It is not always allowed to attach a random process as a debugger to another process. I read somewhere that additional SE_DEBUG_NAME capabilities were required for the debugger process. So I added such logic of requesting them to the program.

In the code, privilege.cpp provides a function to deal with this task. I’ve borrowed this sniipet from MSDN (there was a problem with #pragma that I addressed).

Usage

Call stallattach.exe followed by PID of the process you want to stop. It is recommended to do so from an elevated command prompt (I hope you understand the security consequences of such actions). But it also worked for me if run as a regular user, for some reason.

Sources and disclaimers

The sources are published here: https://github.com/grigory-rechistov/stallattach.

I used a default console application template project generated by the IDE for me. A lot of crap was included into it, such as precompiled headers, resources etc. etc. I let it stay.

I built them using MS VS 2017 on Windows 10 x64. Not sure what exact build dependencies are, which development kits one needs to install etc. You can never know with Windows.

I do not know if this software will be useful to anyone in any way. I am not responsible if it will cause any damage to you. Do not mess with system-critical processes, or be prepared to lose data.

Acknowledgements

A borrowed a few code pieces and ideas from different sources below.

  1. MSDN article https://docs.microsoft.com/sv-se/windows/win32/secauthz/enabling-and-disabling-privileges-in-c—
  2. Writing a basic Windows debugger” by Ajay Vijayvargiya, https://www.codeproject.com/Articles/43682/Writing-a-basic-Windows-debugger
  3. Stackoverflow Q&A: https://stackoverflow.com/questions/4880197 and https://stackoverflow.com/questions/2523099
  4. GetLastError as std::string” by Orjan Westin, https://www.codeproject.com/Tips/479880/GetLastError-as-std-string

Written by Grigory Rechistov in Uncategorized on 29.09.2021. Tags: debugger,


Copyright © 2021 Grigory Rechistov