I have a process that has a CtrlBreak handler by calling SetConsoleCtrlHandler. This handler listens for CTRL_BREAK_EVENT and performs some action (without quitting). This process is not attached to a console. Let's call this the target process.
Next, I have written a separate program which takes a PID and I'd like to start a remote thread at the address of kernel*!CtrlRoutine so that the CtrlBreak handler of the target process is executed, e.g.:
hRemoteThread=CreateRemoteThread(hRemoteProc, NULL, 0,
(LPTHREAD_START_ROUTINE)dwEntryPoint,
(void *)CTRL_BREAK_EVENT, CREATE_SUSPENDED, NULL);
ResumeThread(hRemoteThread);
The problem is, how do I find the address of kernel*!CtrlRoutine in the remote process (dwEntryPoint)?
I saw an example where a program registered its own CtrlBreakHandler, then walked up the stack using __asm to get the address, but this code doesnt work correctly on Windows 2008 Server.
Just to note, I cannot recompile the target process, so I have to do this without modifying the target process.
Microsoft provides a GenerateConsoleCtrlEvent function for this purpose.
You can use DLL injection technique to achieve this. You do it by first creating a DLL whose DLLMain, registers the Ctrl-break Handler. Then you open the target process and write the path to your DLL in its address space using VirtualAllocEx and WriteProcessMemory. Then you launch a remote thread in the target process with LoadLibrary as the entry point and the address of the DLL path as the parameter.
This causes your DLL to be loaded in the target process and DLLMain to be called which will register the CtrlHandler.
You can do all the above things only if your application has privilages to write into target process.
You may refer to this link for the sample code.
You can send the WM_KEYDOWN and WM_KEYUP events to the window handle using the sendmessage api
Related
Assume I have a Windows hook procedure that I am installing on a specific thread using SetWindowsHookEx. When I subsequently call UnhookWindowsHookEx, is my DLL containing the hook procedure unloaded from the target application?
Most of the documentation I've found on the subject would seem to imply that calling SetWindowsHookEx causes an implicit call to LoadLibrary in the target application. Also the docs are very careful to point out that calling UnhookWindowsHookEx on a global Windows hook does not implicitly free the library from all processes that may have loaded it, but are less than forthcoming on the subject of thread-specific hooks. I'm either not reading the documentation carefully enough, or my web search ability has failed me.
There's no difference between a thread specific hook and a global hook. The thread ID parameter is just a filter which determines where the hook is applied - it doesn't change the hooking rules.
So either the thread ID parameter is for a different process and the same rules apply as for the global case - you can't safely inject a FreeLibrary call into another process, or the thread ID is part of your process and there is no reason to call LoadLibary since the DLL is already loaded before the call to SetWindowsHookEx. (Or you passed NULL for the instance in which case there is no DLL)
I suspect the docs are use "global" to mean out of process and "thread" to be in process since that would be the normal case. Hooking a single thread of another process would be a rare event (but seems to be supported. See remarks.)'
This is of course just reading between the lines of the documentation.
According to my research, UnhookWindowsHookEx does not unload the .dll. It is unloaded by the message processing code after a new message is received. Therefore some background processes which almost never receive any messages, may still keep the library locked long after your hook was removed. Broadcasting a WM_NULL message usually helps. I like sending it a few times after unhooking.
SendNotifyMessage(HWND_BROADCAST, WM_NULL, 0, 0);
Can someone please explain to me what is the differance between:
OpenProcess and CreatProcess.
(I am trying to inject a DLL into a program and I dont know which one to use.)
OpenProcess is passed a process ID for an existing process, and returns a process handle for that process.
CreateProcess creates a brand new process, returning a handle to that new process (amongst other things).
If you want to inject into a process that is already running, then you will need OpenProcess.
In relation to injecting a .dll into another process,there are a couple of major benefits and differences between OpenProcess and CreateProcess.
The first is timing. You can inject the dll before the target process has had a chance to perform any of their own code by creating the process in a suspended state (dwCreationFlags with CREATE_SUSPENDED(0x00000004) set). Don't forget to resume the process once you are ready for it to execute.
The second is privilege. The process handle returned by CreateProcess automatically has PROCESS_ALL_ACCESS without the need to set SeDebugPrivilege first. OpenProcess does require your program to gain this privilege before it is allowed to use the PROCESS_ALL_ACCESS flag.
Some other minor things to remember:
CreateProcess cannot be called on a running process, but you can always call OpenProcess after CreateProcess if you needed to for whatever reason.
CreateProcess requires you to CloseHandle both the process and thread handles returned in PROCESS_INFORMATION, where OpenProcess only requires you to CloseHandle on it's return value (No thread handle gets opened).
If you need to change the Environment for whatever reason(unlikely), you'll have to use CreateProcess.
Further reading can be found:
CreateProcess
OpenProcess
process-security-and-access-rights
My application is compiled as 32-bit, and since I run on 64-bit Windows 7, my target(notepad.exe) is 64-bit. When I call SetWindowsHookEx() on the first thread that I find of notepad.exe, the DLL doesn't get injected at all, but there is no error returned. I know it's not being injected because on DLL_PROCESS_ATTACH I display message box with the message Attached, and for DLL_PROCESS_DETACH I display a Detached message in a message box. These messages are only displayed once for when I call LoadLibrary() and another time for when my application exits.
According to the MSDN documentation here:
Because hooks run in the context of an application, they must match
the "bitness" of the application. If a 32-bit application installs a
global hook on 64-bit Windows, the 32-bit hook is injected into each
32-bit process (the usual security boundaries apply). In a 64-bit
process, the threads are still marked as "hooked." However, because a
32-bit application must run the hook code, the system executes the
hook in the hooking app's context; specifically, on the thread that
called SetWindowsHookEx. This means that the hooking application must
continue to pump messages or it might block the normal functioning of
the 64-bit processes.
Does this mean that it's hooking my own process successfully instead of actually returning an error?
Edit : My hook is of WH_CBT type.
You need to read further the docs:
For a specified hook type, thread hooks are called first, then global
hooks. Be aware that the WH_MOUSE, WH_KEYBOARD, WH_JOURNAL*, WH_SHELL,
and low-level hooks can be called on the thread that installed the
hook rather than the thread processing the hook. For these hooks, it
is possible that both the 32-bit and 64-bit hooks will be called if a
32-bit hook is ahead of a 64-bit hook in the hook chain.
In short it depends on the hook type if your dll is injected to the target process at all. If you only want to spy on keyboard and mouse events there is no need to inject yourself into other processes. Windows will call back your hook in your own process.
I suspect your hook type is one of these:
WH_MOUSE_LL
WH_KEYBOARD_LL
which do not cause any library injection into the target process.
What that part of the documentation does not state clearly is that when SetWindowsHookEx fails to inject your 32-bit DLL into a 64-bit process, instead of returning an error, it resorts to using the message loop of the thread that called SetWindowsHookEx to execute the hook procedure, just like how it works with low level mouse/keyboard hooks (WH_MOUSE_LL/WH_KEYBOARD_LL).
How can I detect the name of the application that created my application's process?
For example, if someone wanted, they could call CreateProcess and pass it the suspended flag and inject into my application.
Is there a way to block CreateProcess or to figure out what process created an instance of my application?
I've hooked loadlibrary, createthread and all the other easy stuff but CreateProcess seems like it can bypass that.
I'm doing it for fun and learning, not for real world use. I just haven't seen anything that detects CreateProcess..
Any ideas at all?
You can find the parent process ID using the tool help library:
Call CreateToolhelp32Snapshot.
Call Process32First and Process32Next to enumerate the processes.
At some point you will encounter a PROCESSENTRY32 struct for which th32ProcessID is the process ID of your process.
Read out the th32ParentProcessID member to find the process ID of your parent.
Now that you know the parent process, you can enumerate again to gain information about it.
Be prepared for the parent process to have been terminated before you reach this point.
When using the MiniDumpWriteDump function to create a core dump of a process on Windows, it is recommended (e.g. here, and here) that the MiniDumpWriteDump is run from another "watchdog" process because it may well not work when called from within the same process.
At the moment, our application is calling it in-process on an unhandled exception (we do it from a watchdog thread). Since we sometimes have problems with it not working, we'd like to move it to a separate process.
Now, signalling the other process to start writing the dump is trivial (just use an event, semaphore, you name it) but how do I pass the LPEXCEPTION_POINTERS info I get for the callback function I register with SetUnhandledExceptionFilter to the other process so that it can be passed to MiniDumpWriteDumps ExceptionParam argument??
You also need the MINIDUMP_EXCEPTION_INFORMATION.ThreadId value. The simplest way, and the way I made it work, is to use a memory-mapped file to transfer both the ThreadId and the ExceptionPointers. And a named event to wake up the watchdog. It doesn't matter that the pointer is not valid in the context of the watchdog process.
Use CreateFileMapping + MapViewOfFile in the watched process as part of its initialization, OpenFileMapping + MapViewOfFile in the watchdog. Your SetUnhandledExceptionFilter should then only call GetCurrentThreadId() and copy the tid and the pExcept to the memory mapped file view, call SetEvent() to wake up the watchdog and block forever until the watchdog terminates it.
While Hans answer is correct, I found that an easier way is to use WM_COPYDATA to transfer information from main process to minidump process. Register a class and a HWND_MESSAGE type window with some custom names in minidump process, then wait for WM_COPYDATA message in WndProc. Use FindWindow with same class name and window name in main process to obtain HWND to your minidump window. Use SendMessage with this handle to send WM_COPYDATA message with whenever struct you want to use. This will block your application until minidump process will receive and process it. Note that one of WM_COPYDATA parameters is a handle to window that sent it, but you will still need to use OpenProcess to get a proper process handle to use in MiniDumpWriteDump, so a "minimal" message to send is probably
process ID (to obtain process handle with OpenProcess)
thread ID (to initialize MINIDUMP_EXCEPTION_INFORMATION)
LPEXCEPTION_POINTERS (to initialize MINIDUMP_EXCEPTION_INFORMATION)
This way you will get all the necessary data in minidump's WndProc to call MiniDumpWriteDump. Make sure to set ClientPointers field in MINIDUMP_EXCEPTION_INFORMATION to TRUE since we're debugging external process. Note that when running under debugger in MSVC the call to MiniDumpWriteDump might produce flurry of exceptions like trying to read invalid memory address - simply ignore this, it's normal (and you don't need to intercept any of those)
Once your minidump process finished writing the dump, it will return from WndProc and main process will return from SendMessage. Then you can either terminate your main app or do any other stuff in exception handler (e.g. we show a nice message box to user and close the app gracefully).