I want to monitor when a key is changed/added/deleted to the registry whenever application is being installed or removed. I have tested the sample code from the msdn(link) and it works fine.
But the problem is that it does not tell me which key has actually been modified/added/deleted. How can i retrieve this information using c++?
There are only 3 ways, none of which is both easy and adequate:
RegNotifyChangeKeyValue:
Doesn't give you the info you need, but is very easy to use.
EVENT_TRACE_FLAG_REGISTRY which is part of Event Tracing for Windows
which is what ProcMon uses. It works well, but it's quite difficult to use.
I'm not sure exactly how to use it myself, but if I figure it out I'll post it here.
CmRegisterCallback:
Requires kernel-mode driver, which is a pain in 64-bit.
But it's the most perfect solution otherwise.
Unfortunately Event Tracing for Windows (EWT) does not allow to see full key path in the event. You get only a partial key name and a strange handle with is actually a key control block. It's not so simple to get information from this block.
Yes the process monitor uses EWT, but it does not use Windows Kernel Trace as a provider.
Related
So I have spent that past week and a half working on code to simply setup the hook procedure for wh_shell for a program that will replace explorer.exe in the registry and will run as the main desktop program. There seems to be very little information and sources for using this outside of just the windows API which is a bit undescriptive and doesn't explain everything to a great detail. For some reason I just cant get it to work, no matter if I run it inside of explorer.exe, or if I replace the register and make it the default shell. I'm going to ask a couple of things in this post because I think that if you can answer one of these questions you likely have the answer to more.
So first I just have a question about hooks in general: When I run the SetWindowsHookEx(...) function -resource below- it says for var lpfn that a dll is not necessary if the hook is only used to monitor the current process. Now obviously when monitoring events such as window_created, those are events within a different processes which makes me think that the hookproc has to be within a DLL(which is how ive programmed so far). But this is questionable to me because when u are running SetWindowsHookEx(...) the process I wish to monitor do not yet exist until the user decides to start them. Do these processes notify the system when wh_shell events are being done so that I my hook doesnt need to get placed into every process upon creation, or is it more like when I run SetWindowsHookEx(...) with wh_shell that it will place a hook in all processes when the are created. The second resource states that the system just calls the hookproc when these things happen, so then do I even need a DLL, or what process does it need to be hooked to because I dont think it needs to be hooked into everything.
So second I have a question regarding setting my process as default shell - see resources - the resource states any process that registers itself as the default shell(which I assume is just modifying the registry to my process, if not and there is more please let me know) needs to call the SystemsParameterInfo(...) function. So first, does this func need to be called before running SetWindowsHookEx(...) or is there some expected spot it should be elsewhere in my code? Then in regards to the other variables it doesnt specify for, just curious what the recommended would be to set them as, like what are they set as for explorer.exe, and maybe a few other examples(including things NOT to do).
Finally for the sake of testing, using the console will be the most helpful to me here. The console will be used for input to run functions and commands for now(like open the register and swap back the shell to explorer.exe). If my hookproc is within a DLL, I need it to output some messages, I dont want to muddle the same console and I also dont even know if it will output to the same console, so what might be a recommended or potential solution for outputs(again this is temporary and for testing so it doesnt have to be perfect or even great)?
Also I would think windows 11 shouldn't be an issue, but I havent tested on windows 10 system...
I havent included any code as Im pretty sure most of this stuff can be answered without it and that its so few lines of code that its not like typical questions where its like examine my code and help me, maybe some example code you can show me would be really helpful.
Thankyou!
SetWindowsHookEx(...)
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa
defaultShell
https://learn.microsoft.com/en-us/windows/win32/winmsg/about-hooks#wh_shell
regards to WH_SHELL section
Testing Environment:
Windows 11 vm running in Hyper-V Manager
You haven't mentioned an important parameter in your description and that is the last argument of SetWindowsHookEx, the thread id.
When it is set to 0 then ..
'[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.'
That said, then like everything in Windows programming nothing is as what the documentation states, its as if the documentation is a wish-list Microsoft will like Windows to be when it grows up.
Actually even if you manage to get everything right you will see that the shell messages you will get will be VERY few compared to what the documentation states.
I am working on the same issue and when I get it going I will post the results here.
I've been asked by a client to solve the following pesky issue. They have a custom software that has a tendency of displaying message boxes "left and right" without any apparent reason. For instance, the software itself is an accounting program, and when they take a customer's payment, the message box may be displayed about 3 or 4 times in a row. Each message box plays Windows default sound. Unfortunately the way this software was programmed, the type of sounds it plays is completely wrong. For instance, it may display a warning message box and play the warning system sound when the message itself is just an information. All this is quite annoying for the staff who uses the software.
I tried to contact the vendor who distributes the software, but I hit a deadend with them. So now I am looking for ways to mitigate this issue.
My easiest solution was to suggest to mute the speakers, but unfortunately, they require sound to be present to be able to hear incoming emails, and most importantly, be able to play voice mail from them later. So my solution was to somehow mute message box sounds just for a single process.
From my experience, I know that there're two APIs that may be producing these sounds: MessageBeep and an older Beep.
I also found this article that explains how to use AppInit_DLLs to hook to system APIs. It works great, except that both of the APIs that I need to hook to come from User32.dll and not from kernel32.dll like the author suggests.
There's also this post in the questions section that kinda gives approximate steps to hooking to an API from User32.dll, but when I tried to implement them, there's not enough information (for my knowledge to do it.)
So my questions is, does anyone know how to hook to an API in the User32.dll module?
EDIT: PS. Forgot to mention. This software is installed on Windows 7 Professional, with UAC disabled -- because it is not compatible with UAC :)
As an alternative you can patch you application. Find calls to MessageBeep and overwrite them with nop.
This is the hard way of doing it: if your app is supposed to be running as Administrator on a pre-Vista Windows, you could get the address of the API via ::GetProcAddress(), give yourself privileges to write to its memory page, and overwrite the beginning of the API's code with a "jmp" assembly instruction jumping into the address of your override function. Make sure your overwrite function takes the same arguments and is declared as __cdecl.
Expanded answer follows.
The "standard" technique for API hooking involves the following steps:
1: Inject your DLL into the target process
This is usually accomplished by first allocating memory in the target process for a string containing the name/path of your DLL (e.g. "MyHook.dll"), and then creating a remote thread in the target process whose entry point is kernel32::LoadLibraryA() passing the name of your DLL as argument. This page has an implementation of this technique. You'll have to wrestle a bit with privileges, but it's guaranteed to work 100% on Windows XP and earlier OSes. I'm not sure about Vista and post-Vista, Address Space Layout Randomization might make this tricky.
2. Hook the API
Once your DLL is loaded into the target process, its DllMain() will be executed automatically, giving you a chance to run anything you want in the target process. From within your DllMain, use ::LoadLibraryA() to get the HMODULE of the library containing the API you want to hook (e.g. "user32.dll") and pass it to ::GetProcAddress() together with the name of the API you want to hook (e.g. "MessageBeep") to get the address of the API itself. Eventaully give yourself privileges to write to that address' page, and overwrite the beginning of the API with a jmp instruction jumping into your detour (i.e. into your "version" of the API to hook). Note that your detour needs to have the same signature and calling convention (usually _cdecl) as the API you want to hook, or else monsters will be awakened.
As described here, this technique is somewhat destructive: you can't call back into the original API from the detour, as the original API has been modified to jump into yours and you'll end up with a very tight and nice infinite loop. There are many different techniques that would allow you to preserve and/or call back into the original API, one of which is hooking the ...A() versions of the API and then calling into the ...W() versions (most if not all of the ...A() Windows API's convert ASCII strings into UNICODE strings and end up calling into their ...W() counterparts).
No need to spend time on a custom program to do this.
You can mute a particular application when it's running, and that setting will be remembered the next time you open the application. See https://superuser.com/questions/37281/how-to-disable-sound-of-certain-applications.
There's also the Windows Sound Sentry that will turn off most system sounds, although I'm not aware of any per-application settings for Sound Sentry.
You can use Deviare API hook and solve the hook in a couple of C# lines. Or you can use EasyHook that is a bit more difficult and less stable.
At the moment my info is (and let's keep the context to Windows-7, as WER doesn't work like that on Win-XP) that I have two ways of getting a full memory crash dump for my application:
I can set up WER to generate a local full memory dump of my application
The info is here: http://msdn.microsoft.com/en-us/library/bb787181%28v=vs.85%29.aspx
Add (also for 32bit apps. Do not use SysWow64 node) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps key (possibly app specific subkey ...LocalDumps\MyApplication.exe)
Set DumpType to 2.
Tweak other settings as neccessary
Note: As our application is custom deployed, setting this registry value isn't a problem.
This seems to give me pretty reliable crash dumps with a simple demo app.
Or, I can rig up the dump writing myself - properly with watchdog process and all
I use MiniDumpWriteDump to write the dump and I do this from a watchdog process (as described here, here) to minimize risk of failure.
Question
So, which is the better approach? Given that, when doing it myself, I prudently keep the stuff I do in the crash handler to an absolute minimum, I'm wondering whether the WER approach is as reliable, or whether the WER approach does some more things in-process that
may fail. Any ideas/experiences?
As alternative to doing it yourself, you might look into Google Breakpad, wich is a library and toolset for generating and handling crashdumps.
As we know, windows event logs are different at below Vista (XP and below) and Vista and up, see here Windows Event Logs . On Vista, I am able to understand the API about how to retrieve all event logs.
On the windows XP, I am able to run this sample code. Two things we need to fill in there are:
#define PROVIDER_NAME L"MyEventProvider"
#define RESOURCE_DLL L"<path>\\Provider.dll"
However the question would be there where to get the provider name and its resource dll.
One way I could think of is to iterate through all the sub key under registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\System
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security
From those subkeys, we could get the provider name and its EventMessageFile (although I found out that some subkey doesn't have the EventMessageFile, rather it hasParameterMessageFile).
Is this the only way to do this? Or is there any other better approach?
If you are using WinAPI, than iterating through registry is the only way, as far as I know. And yes, some of providers don't have EventMessageFile, it's normal. Maybe they are just place their insert strings without any message into event log (I can't say exactly).
But, if you can use a .Net, that there is a good EventLog Class, that offers you a bunch of really good methods.
I'm writing a program in C++ to implement the keyboard backlight feature from OS X on MacBook Pro's running a Linux distro. So far, it turns the backlight on, on boot and if no keyboard and mouse events are registered for 20 seconds, it will turn it back off, and of course turn it on yet again when an event is registered. Next thing I need the program to do, is to capture keypresses on the keyboard-backlight-up/down keys, but I'm not sure how to approach this.
I am currently using XScreenSaverQueryInfo to get the idle time of keyboard and mouse events, so a method using X11 API would be okay. I have done a lot of googling but havent found a way that I felt sure about going with. The problem I'm seeing with lots of the methods I found, is that they use keycode to identify the key, but I dont think that would be a viable solution since the program should work for any keyboard-layout available.
Any idea of a method and API I should go with? What would work the best?
Regards,
The normal way to do this is with XGrabKey(). It uses keycodes, but you wouldn't hardcode the keycode, you'd get it with XKeysymToKeycode(). To be more correct you'd also want to redo the grab when you get a MappingNotify (XMappingEvent). (Note, MappingNotify, not MapNotify.) If there isn't a keysym for these keys - there probably isn't on old X versions, but hopefully newer X.org versions have one - then you just have to hardwire the keycode. Which won't be very robust or portable but probably works for everyone on Linux with the same hardware model.
Be prepared that key grabs are global, so if you try to XGrabKey() and something else has already grabbed that key, you'll get an X error - by default that exits the program. Another quirk of XGrabKey() is that it grabs the key with a precise modifier set. For example, to handle both with and without NumLock, you need to grab twice. See Global Hotkey with X11/Xlib
In a normal Linux setup (if you wanted to get a feature like this into upstream projects), the desktop environments don't want lots of separate apps fighting over the key grabs and getting errors. So there will be some central coordination points, such as the window manager or a special daemon might do all the keybindings and forward commands to other processes as needed. So you would probably want to look at patching the same upstream code that handles other special keys like this, if you were trying to get your feature integrated into distributions by default.
Another thing to be aware of is the Xkb API, which is a lot more complicated. There is some brain-bending way to grab keys with Xkb but I don't know of any advantage to going that route.
If you haven't done that yet, familiarize yourself with xev. Start it, give it the focus, and press the keys, to see what's happening.