Launch IE with specific BHO enabled - c++

I have a IE BHO plugin that I only want to be enabled when the user launches IE from my program (The program starts IE using CreateProcess()).
I don't want this BHO to be enabled when a user launches IE from outside my program, as that would mean any problems in the BHO could potentially mess up the user's normal browsing experience.
What's the best way to do this?
One way would be to register the BHO, launch IE and then quickly unregister the BHO. This seems kind of messy though, as a crash in the program that launches IE could cause the BHO to remain registered.

Your approach is very error-prone, I advise against it. Instead, your BHO should always load with IE, but by default it should do nothing. What you need then is a way to tell it "start filtering" or "start recording" or whatever.
You've got lots of choices from there. The simplest is a flag somewhere in the environment (a semaphore, a disk file). You can have a special url, like mybho:start that it watches for.
I've done this many times, it works.
Edit Yes, the BHO will be loaded into memory, together with any DLLs it depends on (though you can wait and load them only when needed via LoadLibrary()).

Related

Using wh_shell hook for custom windows-shell(explorer.exe replacement program) C++

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.

Trying to hook to MessageBeep system API

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.

Determining what memory/values a remote application accesses/changes?

Lets take an example here which is known everywhere in the IT world:
We have a game, for example solitaire, and someone makes and releases a trainer for it that your moves are always '0'.
How do I programatically determine which adresses and what values that "hack" changes?
What way would be the best, if this is possible?
From within the game [injecting/loading my own dll?]
By intercepting traffic between the hack and target process with my own process?
I ask this question because of 2 things:
Protect an application from being "hacked" (at least by the script kiddies)
Reverse engineer a trainer (so you don't have to reinvent the wheel / avoid NIH syndrome)
You can't. Some broken attempts may be setting two addresses and then comparing them (they will find the other address though). Or they can simply remove your compare call.
They can alter any protection function that you use to "programatically determine" to always return false results. They can do anything to your executable, so there is no way.
Unless you hook the kernel functions that open your process to modify the memory. But that is also breakable and if I am not wrong you need to get your "protection kernel driver" digitally signed now.
There is another way in which you load a DLL in every running and newly spawned processes (which will probably alert antiviruses about your program being a virus), with that DLL you hook OpenProcess (and if there is another alternative to it, that too) functions in each process and check if its targeted at your program, and prevent it if so. Search about function hooking. I believe there was something called "MS Detour" or something for it.
And still, the game will not even be close to safe.
To sum up, no way is good to protect your game locally. If you are storing scores or something you should create a server program and client should report every move to server.
Even then, they can create a bot to automatically respond to server. Then the best you can do is somehow verify it is a human that is playing. (maybe captcha or comparing the solving speed with human avarage?)

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.

Windows Shell Extension Not Calling Initialize

I was hoping somebody here had some insight into what could be causing this problem. I've implemented several COM extensions for Explorer that provide ShellIconOverlays and a ContextMenu, and the overlays work perfectly. The Context Menu works fine when I click on the desktop but when I right click in any explorer instance, I can see the interface being queried in the debugger and an instance of IShellExtInit being generated but the initialize function doesn't get called in the explorer instances, but it is called fine from the desktop and a ContextMenu item is queried immediately after.
Has anybody here seen anything like this before?
If you're debugging a shell extension, chances are that you've had occasions to terminate the running explorer.exe process and start a new one. When you started a new one, was it running with the same integrity level as the original?
Do your Explorer settings say to browse files in a new process? If so, is that process running with the same integrity level as the original?
Also, since you're running a debugger, chances are that you built a debug build. Does explorer.exe sometimes try to load the debug build of your DLL and sometimes try to load the release build of your DLL?
OK, I run into the exact same problem here, and it turns out that the issue has to do with
ThreadingModel = Apartment
Basically, what I think you are experiencing, is that the second thread of explorer.exe (desktop runs in STA thread) uses the default (legacy) ThreadingModel - and expects your COM to implement IMarshal to do IPC. Apartment ThreadingModel allows multiple instances of your IShellExt class to co-exist.
Caveat - If you are using ActiveQt to develop Context Menu Shell Extensions, there are few more tricks to use.