Minifilter: Block applications with notification - c++

I'm writing a minifilter to block application execution. The minifilter will request a file scan on IRP_MJ_CREATE to the usermode apps. The usermode application will scan whether to allow the PE file (.exe/.dll/etc) execution or no.
Currently, when the usermode apps says no, the minifilter will issue an access denied status, and cancelling the file open. (Yes, using FltCancelFileOpen)
The problem when issuing access denied return value is, from the user perspective, they will get a message box from the system like this:
Another example, when blocking the specific dll from being loaded, another messagebox will appear:
What I want to accomplish is to still deny the open but suppress the message box and have a notification of my own, which is a user friendly error message indicating the apps were blocked. Example are like windows 8 smartscreen feature, which will notify the user when running blocked exe without any messagebox saying access denied or similar.
How can I do that?

Let's take the DLL example. You get that error because there's code in Windows equivalent to
if (!LoadLibrary(szDllName))
{
MessageBox("Application Error", ...);
}
else
{
DllMain = GetProcAddress("DllMain");
DllMain(DLL_PROCESS_ATTACH);
So, if you don't want the first branch of the code to be taken, you should allow the DLL to load. There's no third option.
The Windows 8 example is misleading. If you're Microsoft, of course you can add that third option.
[edit]
On second thought, did you cancel the operation using FltCancelFileOpen ? If not, then how did you do it?

Related

Is there a way a customer can force a crash (which then will generate a minidump) during a "long" Windows API call?

Our app is "hanging" at a customer site (not really, it's just a really long call to some Windows Networking API call, where there is a disabled VPN adapter, and it needs to time out - minutes?). We cannot duplicate it (we don't have his VPN setup), but customer can easily duplicate it.
Our app generates mini dump (*.dmp) files when it crashes. Is there a way to get an end-customer to generate an immediate crash (specifically during this long API call), so we can see where it is hanging?
I have tried "Ending the Process" via Task Manager, but that must "gracefully" shut down the app, because a .dmp file is NOT generated using Task Manager.
This is a release build of an MFC C++ app.
You don't need to crash to generate a dump file. Simply open up Task Manager, go to Processes tab, rightclick the respective process and choose Create dump file:
Once the dump is written to disk Task Manager will pop up a dialog informing the user, where the dump file is located. By default it is %temp%\<image name>.DMP:
For 32 bit applications, to create a 32 bit dump file, run the 32 bit version of Task Manager from Window's SysWOW64 folder : e.g. c:\Windows\SysWOW64\Taskmgr.exe
You can use WinDbg to create the minidump:
http://wiki.zimbra.com/index.php?title=Creating_a_Core_Dump_from_a_Running_Process_using_WinDbg
This will tell you where it is, when you break. Obviously, it won't use your handler to create the dump, but if you're just worried about the hang location, this should be sufficient. Visual studio has similar functionality to create a dump from a running process.
If you want to test your crash reporter, this will provoke a nice access violation:
int *p = 0x0;
*p = 0xbadf00d;

Writing to the Windows Security Log with C++

I have been tasked with writing entries to the Windows security log. The entire project is Win32 C++ code. I have already written (with help from various online resources) a logging class that handles registration, deregistration, and code for executing the ReportEvent() call. Also, I've done the mc.exe and rc.exe steps for my event logging, if that helps establish where I'm at in the project.
My question is a multi-parter:
I've noticed at Filling Windows XP Security Event Log that there are some who believe this is not allowed by Windows. Others ( How to write log to SECURITY event Log in C#? ) imply otherwise. Possible or not?
If it is possible, how to get it to write to the security log. Is it as simple as specifying "Security" as my source name when calling RegisterEventSource()?
As far as deregistration, when should that occur? When the app is uninstalled? When the app closes? When the log entry is written?
How do I look up my log entries? I look in the Windows Event Viewer, but I don't see the entries I add with my test app, despite all the appropriate return values from the system calls. Where would I look up the events that I specified with a source name of "yarp" when I made my call to RegisterEventSource()?
For the moment, I'll just deal with the first question, because the answer to that probably renders the rest irrelevant.
Only Local Security Authority (lsass.exe) can write to the security log. This isn't a matter that something else attempting to get the privilege will fail -- it's a matter of there not being a way for anything else to even request the privilege at all (and this is by design).
From there, about the only answer to your other questions is "Sorry!"

Windows - How do I disable the "Wrong Volume" error message

My application is reading/writing data to a removable media (USB DOK) in the background. The problem is that when the USB is removed while the app is working, the computer pops up an error message:
Wrong Volume
The wrong volume is in the drive. Please insert volume into drive E:.
Cancel Try Again Continue
This happens during operations such as GetFileSize, ReadFile. Obviously, since the app is supposed to work in the background, I would like to suppress those messages and fail silently.
BTW - It seems that the process giving those message is not my process, but CSRSS.EXE (although the cause is definitely the operation from my process).
One direction I am considering is switching to NtQueryInformationFile, NtReadFile, etc., but I'd rather not...
Thanks
Try calling:
SetErrorMode(SEM_NOOPENFILEERRORBOX);
At the beginning of your main function.
From the documentation:
The system does not display a message box when it fails to find a file. Instead, the error is returned to the calling process.
I suggest you properly disconnect your hardware using the icon in the windows system tray so that it's not being accessed when you pull it out of the drive. Or at least exit your ap first.

Why wont my windows service write to a file continuously?

I have created a windows service that checks installed printers and updates a file currently located at "C:\App\Data\info" (no file extension) Very simple, all it does is call EnumPrinters with the correct flags and dumps PRINTER_INFO_2 to a file.
Everything works exactly as expected in Visual Studio 2010, in the "testing" project leading me to believe the issue is not in my service. As soon as I install this as a windows service it stops looping. It will run through the loop once and never again.
Code Reference:
I am using the template from here: http://www.kencotutorials.com/WindowsService.aspx
and have only changed the service class file.
Initial thoughts are either security permissions or the wait function not returning.
Edit: I have already checked the whole file system to see if its being written elsewhere and confirmed that it is not.
This is the service loop function that is called by the template.
void CMyService::MyServiceLoop(void)
{
CheckPrinters(); // updates a PRINTER_INFO_2 struct with all installed printers
WritePrinterFile(); // writes the file (i know there's no issue with the actual writing)
Sleep(10000);
OutputDebugString("Done sleeping");
Return;
}
I have added OutputDebugString("Shell loop entered") at the start of the shell app loop.
I have also added OutputDebugString("Waiting for object") in front of the call to WaitForSingleObject()
The loop seems to hang on the WaitForSingleObject. Last message in DbgView is "Waiting for object".
Could be a lot of reasons. I'd recommend you add some OutputDebugString() calls (Win32 API function) and get DbgView.exe from Microsoft to see what is going on. Also, doesn't sound like you are doing this, but make sure you aren't writing to a mapped drive or network location, since your service most likely doesn't have access to those.
When you set up your Windows Service, did you specify an account on the Log On tab?
http://www.coretechnologies.com/WindowsServices/FAQ.html#AppNotWorkingFromService
The default Local System account almost surely doesn't have the rights to use the printers so be sure to set an account that can access the printers normally.

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.