I’m trying to write a little tool to simplify inventorying my removable media. Getting and storing a list of files on the media is simple enough, but I want to be able to catalog them according to what type of drive they are.
There is an API function to get the drive type, but it is old and limited to floppy, CD, fixed, removable, network, and RAM. it does not give fine-grained information to determine whether a drive is a flash-drive or a memory-card (let alone even more detailed like what kind of memory-card). Even a newer function meant for USB drives doesn’t seem to specifically differentiate between types of USB media.
Is there a reasonably easy and reliable way (preferably C++) to determine that? (Yes, I know that some media can be modified to present as different types, but it only needs to work well enough for normal, standard media.) There is definitely some way to do this because Windows contains different icons for all kinds of media in shell32.dll, and Explorer usually uses the correct one when you plug them in.
Related
Scenario: A critical computer system is operator-controlled via standard USB keyboard and mouse. Also, there is a DVI-monitor connected to view the operator-targeted GUI. The computer system runs a soft-PLC system based on Windows 7 Professional or, alternatively, Windows Embedded Standard 7 (the "system software").
Question: Is there a software solution, to detect the loss (disconnect/failure) of USB HID-devices such as the keyboard or mouse, and the single DVI-display? This is important, since the critical system can no longer be expected to function properly, without the operator able to manipulate it or see displayed content.
Own considerations: This likely requires low-level WINAPI calls, which is fine. I am thinking that a windows service might be constantly seeking to enumerate the number of keyboards and displays - perhaps even identify them via model or serial number. If this enumeration and/or identification reaches zero or fails entirely, the system-software must of course react fast and appropriately (i.e. go to fail-mode or similar).
As far as I see it, this is general issue with all critical operator-controlled systems. Question is then: Is there already software or hardware for this in existence perhaps?
Note: Operator is always human.
Alas, as for an answer this isn’t going to be much more than a “read the docs” plus some links... Sorry.
First, MSDN documentation.
RegisterDeviceNotification
Detecting Media Insertion or Removal
Talking to USB devices, start to finish (Windows Store app)
I found a C# class on CodeProject.com that does this; the accompanying article is pretty good.
Detecting USB Drive Removal in a C# Program.
I admit that the last time I did anything like this was some years ago, and only for CD notifications. I’ve since lost the code (both my primary and backup hard drives failed within days of each other, LOL).
Preamble:
Recently I came across an interesting story about people who seem to be sending emails with documents that contain child pornography. This is an example (this one is jpeg but im hearing about it being done with PDFs, which generally cant be previewed)
https://www.youtube.com/watch?v=zislzpkpvZc
This can pose a real threat to people in investigative journalism, because even if you delete the file after its been opened in Temp the file may still be recovered by forensics software. Even just having opened the file already puts you in the realm of committing a felony.
This also can pose a real problem to security consultants for a group. Lets say person A emails criminal files, person B is suspicious of email and forwards it to security manager for their program. In order to analyze the file the consultant may have to download it on a harddrive, even if they load it in a VM or Sandbox. Even if they figure out what it is they are still in this legal landmine area that bad timing could land them in jail for 20 years. Thinking about this if the memory was to only enter the RAM then upon a power down all traces of this opened file would disappear.
Question: I have an OK understanding about how computer architecture works, but this problem presented earlier made me start wondering. Is there a limitation, at the OS, hardware, or firmware level, that prevents a program from opening a stream of downloading information directly to the RAM? If not let's say you try to open a pdf, is it possible for the file it's opening to instead be passed to the program as a stream of downloading bytes that could then rewrite/otherwise make retention of the final file on the hdd impossible?
Unfortunately I can only give a Linux/Unix based answer to this, but hopefully it is helpful and extends to Windows too.
There are many ways to pass data between programs without writing to the hard disk, it is usually more of a question of whether the software applications support it (web browser and pdf reader for your example). Streams can be passed via pipes and sockets, but the problem here is that it may be more convenient for the receiving program to seek back in the stream at certain points rather than store all the data in memory. This may be a more efficient use of resources too. Hence many programs do not do this. Indeed a pipe can be made to look like a file, but if the application tries to seek backward, it will cause an error.
If there was more demand for streaming data to applications, it would probably be seen in more cases though as there are no major barriers. Currently it is more common just to store pdfs in a temporary file if they are viewed in a plugin and not downloaded. Video can be different though.
An alternative is to use a RAM drive, it is common for a Linux system to have at least one set up by default (tmpfs), although it seems for Windows that you have to install additional software. Using one of these removes the above limitations and it is fairly easy to set a web browser to use it for temporary files.
I would like to know how can a single specific program/window can be video recorded in Windows. There are some ways in which you can video record the entire screen, or a specific region (using GDI, DirectX, etc) but what I specifically want is to record a single program/window, even though if that program/window is or isn't on focus or it is moved. The only program that I've seen capable of doing this is Microsoft Lync, and I am really interested in who it's done. Is there any SDK, framework, etc that I can use for achieving this ? (it doesn't matter the programming language, either it's C#, C++, etc).
I need to develop an application that monitors, and potentially filters (rejects the calls), file operations.
It appears that developing a minifilter is the "standard" solution.
another potential method is using API hooks.
are these relevant solutions? (I read in some places the an API hook may not be suitable - but no explanation was given)
are there other options?
API hooking (at least in kernel space) is essentially not supported by microsoft. On x64 (starting from Vista and up) patchguard will usually kill the machine if it detects SSDT hooking or any change whatsoever in critical components of the system. API hooking is very hard to get on a system-wide level because the synchronization primitives that windows uses are not exported so even if you manage to hook the code there is not guarantee that the machine won't crash due to a funky value of EIP at a given moment (this is especially valid when you are unloading a driver that has hooked a function).
Probably your best bet to do it - without using minifilter driver is to try and to direct memory kernel object hooking. You might want to look at OBJECT_TYPE_INITIALIZER definition structure which every object windows has (FILE, EVENT, PORT etc - google around to see them) has as its member. You are particularly interested in the *Procedure function pointers.
It all comes down to what you want/need to accomplish.
If you just need file operations (in the kernel level, file open / file close), and you need it system-wide than I would go with minifilter. It is a long, tedious and time-consuming road, but safer (check out Sysinternals procmon to see what you can get using this method).
If you need a more application-specific control, or if you would like control over the WINAPI level, go with API hooking. It is easier to develop, but there are lots of "mines" that blow up in your face during the way (check out EasyHook, its doing a pretty good job with minimum work).
good luck!
If you are preventing user access to certain resources (files) from a security perspective the correct way is a minifilter. This is because it's the only way you are sure that the user cannot access the filtered resources.
If you use API hook you can intercept calls at kernel32.dll (CreateFileW, FindFirstFile, etc., etc.) but an attacker can uses Native API (ntdll.dl). Of course, you can intercept at Native level (it's more difficult since it's undocumented) but attackers can use differents APIs at kernel switch level. At that level it's not portable to hook. It's almost impossible to prevent creative attackers to access to resources using API hook, that's why it's not recommended for security software.
In my opinion, API hooking is a good option for monitoring. If you want to see what an application is doing, it's very good to use API hook since you can intercept higher level functions than in kernel-mode.
If you can accomplish the task without the hooks - do it. Because hooking is not a supported way of developing applications. There is a lot of pitfalls and antivirus software will treat your application as more dangerous. Also you may face problems with newer/older versions of operating system.
But take into consideration that user-mode code is much easier then kernel-mode. So if user-mode hooks can satisfy your requirements then you may think about them.
I got a follow up question by mail, so i'm adding here the solution we used
The project was canceled before it wen't live, but we evaluated a product (Eldos CallbackFilter) that allows writing kernel filters using user space code.
The product has a generic kernel driver that communicates with user space code that defines the filtering logic.
I would have to contradict LordDoskias as, OBJECT_TYPE_INITIALIZER is not a documented object and this can, has and will change with OS patches and updates.
Do not approach this problem this was as it will only cause more problems and not solve anything.
Not to mention the patch guard which will BSOD the system if you modify system structures.
If you want to restrict access to files there is no way around it than simply using a minifilter. There are several Microsoft samples here that you can draw inspiration from and also learn to implement your driver the correct and supported way.
Lastly and more importantly it is illusory to think that you will be able to block everything you want by hooking techniques and I will just give you one example: mapped files.
Here is a scenario involving notepad which uses mapped files to write it's data to disk.
CreateFile -> obtains file handle -> you see this
CreateFileMapping -> obtains mapping handle -> you don't see this
CloseHandle(FileHandle) -> you see this
MapViewOfFile returning a memory buffer being page backed by the file -> you don't see this
Modify the memory buffer -> you don't see this
Unmap and close the FileMappingHandle -> you don't see this
Async the memory manager's system worker threads make paging writes to the file to keep it in sync. Even after all the handles have been closed or during the in-memory change of the buffer, depending when the OS wants. -> you don't see this
This is what you are missing with hooking. And this is just one scenario. There is a multitude of them, so please do things the right way.
How would that change if you use a minifilter ?
You would of course catch the CreateFile, CreateFileMapping as well ( check FltAcquireForSectionSynchronization callback) and then from the minifilter you will see all the PAGING_WRITE coming from the memory manager (see IoGetTopLevelIrp()) in your Write dispatch callback.
Good luck further.
I'm concerned about the dangers of using memory-mapped IO, via CreateFileMapping, on FAT filesystems. The specific scenario is users opening documents directly from USB sticks (yeah, you try and ban them doing this!).
The MSDN Managing Memory-Mapped Files article doesn't say anything about file system constraints.
Update
I didn't have any real reason to be concerned but a vague feeling that I'd read about problems with them at some point (my career spans over 25 years so I have a lot of vague depths in my memory, all the way back to 8-bit micros!). The issue of whether or not they should be supported is pretty important for me to recommend so I wanted to ask if anyone could corroborate my concerns. Thanks for putting my mind at rest.
Memory-mapped files is one of my favorite features. It's absolutely no danger. It's one of the base extremely optimized Windows I/O features. If one starts an EXE or load indirect a DLL it is implemented internally as memory-mapped file mapping.
It is supported on all types of file systems including FAT.
By the way atzz say that memory-mapped files are allowed on network drives. I can add it is not only allowed, but it is strictly recommended to use memory-mapped file also with files from network. In the case the I/O operation will be cached in very good way, which is not done with other (C/C++) I/O.
If you want that the EXE will not crash if you open it from the CD or network one can mark Program Executable with one bit in the header (linker switch /SWAPRUN see http://msdn.microsoft.com/en-us/library/chzz5ts6.aspx). There are no option for documents opened from USB stick.
But what exact problem do the users have? Do they don't use "Safely Remove Hardware" Icon? Then they have to learn to do this exactly like they have to learn to not switch computer power, but shutdown the computer properly.
Could you explain why you find dangers to use memory-mapped files, and in what situations you have problems and is usage of other I/O operation has no such problem?
Yes it does. It even supports mapping of files on CDFS or on network drives. What is the source of your doubts?