Detecting child processes - c++

Is there a way (in C++ & windows XP) to detect if one process spawns any other processes?
for example,
write.exe in system32 spawns wordpad.exe then disappears, is there a function that tells me if the process is about to do this?
for those interested i solved the problem using this section of msdn:
http://msdn.microsoft.com/en-us/library/aa390425(v=VS.85).aspx

Nothing in the Win32 API for this. However, it is supported through WMI with the Win32_ProcessStartTrace query. You'll find some C# code that demonstrates the query in my answer in this thread. Writing WMI code in C++ is fairly painful, you'll find a link to boilerplate code you have to write in the MSDN Library article.
Do beware that this isn't particularly fast. It isn't clear to me how much help the WMI provider gets from the kernel to generate the notification but given the speed it quacks like polling. In other words, the process is likely to be well on its way by the time you get the notification. This is otherwise par for the course on a multitasking operating system.

You can enumerate over the process tree, which identifies running processes and their parents. This is the inverse of what you want (you want to identify child processes, not parent processes). But of course by keeping track of parent process IDs while enumerating, you can identify which sub-processes a given process has spawned.
To do this, call CreateToolhelp32Snapshot and then use Process32First and Process32Next to enumerate the processes. The enumeration will fill in a PROCESSENTRY32 struct that contains a th32ParentProcessID member.
This is a polling method; there may be another way of actually hooking the CreateProcess function, but I don’t have any information about that.

I think you would need to make a global hook DLL that attaches itself to every running process. DLL then finds a place where a function call to CreateProcess is mapped to actual CreateProcess from kernel32, and change a table entry to redirect the call to it's own code to "detect" the call to CreateProcess. All this assuming that some user firewall will not prevent your global hook from executing.

Related

Windows Parent and Child Process creation

I want to create 5 child process in Windows using C++. But I am confused that CreateProcess asks for lpApplicationName and not like fork in which I can figure out whether I am child or parent. how to do this in Windows
Unfortunately the CreateProcess function can only be used to load a program and start a new process for that program.
You can however use CreateProcess to simulate the fork functionality, by asking it to load the program you are already running, and then ask it to jump to the correct position. This is what is (or was, at least) done by Cygwin, as referenced by this old answer.
It is usually preferable in Windows to use threading rather than multiple processes, because processes are much heavier objects in Windows than in UNIX.
However, you can do what you're asking by passing the name and path of your application to CreateProcess (using GetModuleFileName if you don't already know it) and including a command-line argument to tell your application that it is being launched as a child process.
Keep in mind that the child processes will be started from scratch, they will not have a copy of the parent's memory as they would if you were using fork.

Hooks for mouse - limitations and performance

I have some question about WH_MOUSE. From what I've read, by putting the hook into a DLL it injects processes. Does it mean that capturing the mouse will work on my desktop, menu start etc. too? And what about title bar of applications? I've seen some posts over the Internet with such problems, but don't know if they failed with something or there's some kind of limitation (or another approach).
I also have a question about performance between WH_MOUSE and WH_MOUSE_LL. I found somewhere that the WM_MOUSE is faster than WH_MOUSE_LL, but is it really noticeable? If so in what situations it can slow system that much that we can notice that? If I want to record only clicks of the mouse and keyboard would WH_MOUSE_LL be efficient?
Thanks!
Both hooks get you mouse input anywhere on the screen (other than cases listed below), they are essentially the same from this high-level functional point of view.
Both are subject to UIPI: neither hook will get you mouse input when the mouse is over an elevated process.
Low-level hooks don't require a DLL, so can be used by C#. The other type requires a separate DLL written in unmanaged code (C/C++).
If running on a 64-bit machine, where you can have a mix of 32-bit and 64-bit processes running, a low-level hook will receive events from both types of processes, but the other type of hook will only see events from processes of the same 'bitness' as itself (this limitation derives from the use of a hook DLL; a 32-bit hook DLL can only hook into 32-bit processes, and similarly for 64-bit.) So if you care about this case, with a LL hook you need just one process, whereas with the other type of hook, you need two cooperating processes, one for 32 and one for 64.
LL hook requires a message loop to be running.
LL hooks are simpler to write, since the callback happens in your own process, so you can access your own global variables and so on. With the other type of hook, the callback happens in another process, so you have to do extra work to communicate the information back to your main process. (In both cases, you should keep the code in your callback minimal; just do basic filtering and checking, do any significant work from your mainline code, not the callback.)
LL hooks are 'slower' because the input notification is marshaled to your process, processed there, and then the context switches back to the original process again. With the other type of hook, there's no context switch. This may or may not be noticeable to a user, however, and may depend on what you are doing in the callback, how your are handing the information, how long the hook is installed for, and other factors.
The issue with the title bar seems to be addressed in this question; summary is that you get WM_NCMOUSEMOVE messages over the titlebar (and other non-client areas), WM_MOUSEMOVE elsewhere, so you have to check for both.
My 2c: if you are writing a simple utility or coding for fun, go with _LL; it's considerably easier and handles most of the trickier cases for you; you don't have to worry about 64/32bit issues or communicating between processes, so you get up and running sooner. When you've got your app logic working, you can convert the code to the other type of hook later if needed. On the other hand, if you want a more 'professional' app that is a 'good citizen' and minimizes its impact on other apps, then the other type of hook may be more appropriate; but as with all things perf releated, measure first, don't assume, so even then perhaps best to start of with a _LL hook anyway.

Monitoring open programs with Win32

I've searched the web, and various forums, but I can't find one thing, how to continually monitor open programs and then close another program (not the one being monitored) if something happens to the program being monitored.
For example, say that there is an already open Notepad window, and then the user or some other program opens a Windows Explorer window. I want to know how to close the Notepad window without interacting with the Windows Explorer window (other than realizing that it is indeed open), as well as closing the Notepad window if the user closes the Windows Explorer window.
Thanks in advance! :D
On windows, you can use PSAPI (The Process Status API) to know when processes are started and terminate. The EnumProcesses function can give you this information.
A more reliable method to determine that a process terminated (since process ids can be reused) is to wait on its process handle (you will need the SYNCHRONIZE access right) which you can obtain using OpenProcess and the process' id obtained from EnumProcesses.
To terminate a process, there is always TerminateProcess. To call TerminateProcess, you will need a handle to the process with the PROCESS_TERMINATE access right. All of this assumes that you have the privileges needed to perform these actions on the process to be terminated.
One thing to be aware of is that processes and programs - or at least what the user regards as a program - are not necessarily the same thing.
If you use the PSAPI to get a list of all the processes running, you'll see a lot of background process that don't correspond to open windows at all. There's also cases where a single process can have multiple top-level windows open. So while you have simple cases like notepad where once notepad.exe process corresponds to one Notepad window, you also have cases like:
Word, where one word process handles all the word documents currently open (one process, many windows)
Explorer, where a single exploere.exe process handles all the open explorer windows, and also things like control panel windows and the task bar.
Chrome (and other browsers), where each tab gets its own process (many processes, one window!)
Using TerminateProcess is perhaps not the best way to close an app: it's not directly equivalent to clicking the close button. It forcibly terminates the entire process there and then, without giving it any chance to clean up. If you do this on Word, when it restarts, it will go into 'recovery mode', and act as though it hadn't shut down cleanly the last time. It's best left as a last resort if a process has stopped responding. Also, if you TerminateProcess on a process like Word or Explorer, you'll end up closing all windows owned by that process, not just one specific one.
Given all of this, if you want to essentially write some sort of program manager, you might be better off taking a window-centric approach rather than a process centric one. Instead of monitoring running processes, monitor top-level application windows.
There are several ways to listen for changes to windows; SetWinEventHook with EVENT_CREATE/DESTROY is one way to listen for HWNDs being created or destroyed (you'll need to do filtering here, since it will tell you about all HWNDs - and more! - but you only care about top-level ones, and only app ones at that). SetWindowsHookEx may have other options that could work here (WH_CBT). You can also use EnumWindows to list the windows currently present (again, you'll need to filter out owned dialogs and tooltips, currently invisible HWNDs, etc).
Given a HWND, you can get process information if needed by using GetWindowThreadProcessId.
To close a window, sending WM_SYSCOMMAND/SC_CLOSE is the best thing to try first: this is closer to clicking the close button, and it gives the app a chance to clean up. Note that some apps will display a "are you sure you wish to close?" dialog if you haven't saved recently - again, it's consistent with clicking the close button with the mouse.
The most well-known way of doing this on Windows is to use the Process Status API. You can use this API to enumerate processes However, this API is annoying in that it doesn't guarantee you get the full list or processes.
A better way to enumerate processes is using the Tool Help Library, which includes a way to take a complete snapshot of all processes in the system at any given time.
You need the Microsoft PSAPI (Processes API), for example to see the open processes you can use the openProcess function.

How can I detect message boxes popping up in another process?

I'd like to execute some code whenever a (any!) message box (as spawned by the MessageBox Function) is shown in another process. I didn't start the process I'm monitoring.
I can think of three approaches:
Install a global CBT Hook procedure which tells me whenever a window is created on the desktop. Then, check whether the window belongs to the process I'm monitoring and whether the class name is #32770 (which is the class name of dialogs according to the About Window Classes page at the MSDN). This would probably work, but it would pull the DLL which contains the hook procedure into virtually every process on the desktop, and the hook procedure gets called a lot. It smells like a potential perfomance problem.
Try to subclass the #32770 system window class (is this possible at all?) and look for WM_CREATE messages in my custom window procedure.
Intercept the MessageBox Function API call (even though the remote process is running already!) and call my code from the hook function.
So far, I only know that the first idea is feasible, but it seems really inefficient. Can anybody think of a simpler solution than that to this problem?
I can't think of any efficient solution that doesn't involve injecting code into the other process (this is basically what many types of hooks do by the way). But if you are willing to go down that path, you can intercept calls to MessageBox.
Spend some time stepping through into a call to MessageBox in the debugger in assembly language mode and you'll see that it's an indirect call through a lookup table (that's how exports work). so if you can get your code into the process, you can patch the table to jump to your code instead.
See http://www.codeproject.com/KB/threads/completeinject.aspx for code showing how to inject a dll into another process.
I think: Approach 2 is impossible. Approaches 1-3 require dll, that is loaded into all processes, and approach 3 is "more right". I suppose searching windows by timer is not suite by some reasons?
I would go with the first option. You should be able to get away with only installing the hook for the main UI thread of the app you're monitoring, but if that doesn't work, even global CBT hooks aren't terribly resource intensive in my experience. Of course, you'll want your hook DLL to contain as little as possible other than the hook logic itself. If you need anything bulky, link it dynamically only when you know you're in the right process.

Detecting multiple launches of a Windows application

What's the approved way to handle second, third, etc launches of application in Windows (C++) application? I need the running (first) instance to take some special action (pop up a dialog) in this case, but for the secondary instances to terminate.
On Mac, AppleEvents sends you a 're-open' message in this scenario. Mozilla on Windows uses DDE to check for an existing instance and pass the command line through. It feels like a pretty nasty solution, all the same.
The windows way is to open a named mutex and, if you can acquire it, it means you're the first instance, if not, there is another one. At this point you can register a windows message (the function is literally RegisterWindowsMessage) which gives you a WM_ msg you can send to all windows and only your app would know to catch it, which allows you to tell your initial copy to open a dialog box or w/e.
How to limit 32-bit applications to one instance in Visual C++
"The method that is used in this article is the one that is described in MSDN under the WinMain topic. It uses the CreateMutex function to create a named mutex that can be checked across processes. Instead of duplicating the same code for every application that you will use as a single instance, the code that you must have is in a C++ wrapper class that you can reuse across each application."
SendMessage Function
"Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message."
"Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function to obtain a unique message for inter-application communication."
RegisterWindowMessage
"The RegisterWindowMessage function defines a new window message that is guaranteed to be unique throughout the system. The message value can be used when sending or posting messages."
On windows there is not really solution for that at least not out of the box.
You can use mutex to do such things, basically the app check for the mutex at startup create it if it doesn't exist.
There is one issue with CreateMutex method that you might need to consider - the named mutex might have been created by a third party. Now, most of the time, this won't be an issue, there would be no reason for someone else to block your application. However, if you're making a program that does something important, it may be an issue. Consider, if your program was a virus scanner, a virus could disable it by creating the mutex.
Usually, CreateMutex should do the job, but you should be aware of the limits of this method.