Detecting and blocking microphone usage in kernel

Hi guys,

For my next task, I’m trying to find a way to implement a security kernel driver for microphone usage. I found several threads which talk about this, but didn’t find up-do-date detailed information.

I’d like to be able to do the following:

  1. Block selective applications from accessing the microphone.
  2. If not possible, block all applications from using the microphone.
  3. If not possible, notify the user when the microphone is being used.

From the information that I found, modern Windows versions use a memory-mapped buffer to transfer the microphone audio stream. That made me think that I might be able to control which apps are able to map the relevant buffer and access it, which will allow to implement 1. For this to work, I need to be able to identify the relevant handle, which I don’t know how to do.

Another possibility that I thought of is hooking the act of writing data to the said buffer by the device driver. If I can do that, I can e.g. replace the data with silence, and by this implement 2. But unfortunately, I don’t know how to approach it just yet.

Can you please shed some light on what possibilities I have?

I dunno, but the whole thing sounds like a contrived solution to the imaginary problem to me…

If you don’t want to be recorded by the PC just don’t plug in the microphone. In general, if you don’t want some device to be present at the moment you can always disable or eject it via the Device Manager.

Just look at the whole thing from the potential buyer’s perspective. What is the point of buying some “security product” that offers the functionality that is readily available anyway???

Anton Bassov

xxxxx@gmail.com wrote:

I’d like to be able to do the following:

  1. Block selective applications from accessing the microphone.
  2. If not possible, block all applications from using the microphone.
  3. If not possible, notify the user when the microphone is being used.

From the information that I found, modern Windows versions use a memory-mapped buffer to transfer the microphone audio stream. That made me think that I might be able to control which apps are able to map the relevant buffer and access it, which will allow to implement 1. For this to work, I need to be able to identify the relevant handle, which I don’t know how to do.

No, it’s not that easy.  The key problem in your scheme is the magical
protected Audio Engine process.  In the post-Vista world, audio drivers
communicate only with the Audio Engine.  The Audio Engine then
implements the rest of the audio graph, and applications communicate
with the Audio Engine.

Thus, in a WaveRT driver, the hardware’s circular buffers are always
mapped into the Audio Engine process.  The apps do not map that buffer.

 

Another possibility that I thought of is hooking the act of writing data to the said buffer by the device driver. If I can do that, I can e.g. replace the data with silence, and by this implement 2. But unfortunately, I don’t know how to approach it just yet.

Another dead end.  In a WaveRT environment, the driver is not involved
in the streaming data flow in any way.  That’s the huge advantage of
WaveRT.  The driver maps the hardware’s circular buffer into the Audio
Engine, but after that, the hardware writes directly into that circular
buffer, and the user-mode Audio Engine reads from that buffer.  There is
no kernel involvement in streaming.

Can you please shed some light on what possibilities I have?

What you’re asking is contradictory to the Microsoft audio philosophy,
and that’s never a happy road to travel.  There are good reasons for
this, based on the history.  Originally, audio apps connected directly
to the kernel driver stack, which included not only the audio driver,
but the system audio processing, the kernel mixer, etc.  Then, some
engineer got the bright idea, “hey, I can ‘add value’ to the audio stack
by including my audio processing, which I know how to do better than
everybody else”.  Pretty soon, there were dozens of companies trying to
“add value” by inserting their clever filters into the audio stack, and
the professional audio companies started to complain that their
latencies were totally unpredictable from system to system.

That (and DRM) is primarily what drove the audio system redesign in
Vista.  In the new design, Microsoft is very strict about adding value. 
It is impossible to “add value” generically.  You “add value” by
inserting system Audio Processing Objects, which are user-mode DLLs that
live in the Audio Engine.  However, APOs are installed via the INF for
hardware, and are associated with a single piece of hardware.  You can’t
add them globally.  Plus, an application can always request “exclusive
mode”, which bypasses any APOs.

Given all of that, what you ask may not be possible.  I would suggest
you ask your question on the [wdmaudiodev] mailing list
(http://wdmaudiodev.com).  All the cool audio kids hang out there,
including a couple of very helpful members of the Microsoft audio team.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thank you for the reply Tim.

The apps do not map that buffer.

By “mapping” I meant that they access it, so they need to map (not sure that that’s the correct word) the buffer onto their virtual memory. While the mapping object is owned by the Audio Engine process, an app that accesses the microphone needs some kind of handle to it to call MapViewOfFile. So perhaps there’s a way to prevent from selected apps to gain that handle.

By debugging audiodg.exe I see that it calls DuplicateHandle. Can I intercept NtDuplicateObject calls in a kernel driver, and disallow undesired calls? (I’m new to kernel development)

Also, how protected is the audiodg.exe process? I’m able to attach a debugger to it, which means that a malware can gain access to it too. I guess that a malware can as well communicate directly with the audio drivers, as audiodg.exe does. So for a proper security solution, I might add protection to audiodg.exe and the audio driver.

Any thoughts on this?

> 1. Block selective applications from accessing the microphone.
To use a memory-mapped buffer you have to issue before CreateFile() to receive handle. Correct? CreateFile() thread may be impersonated. You receive both PID and User and may denied unappropriated operation.

  1. If not possible, block all applications from using the microphone.
    Few years ago I created Device Protection subsystem without driver completely. :slight_smile:
    I used Configuration Manager, enumerate, control and disable all devices illegal defined protection schema. The easiest way how to do it you may use DevCon.exe example from DDK and see in its source.

On Jun 14, 2018, at 4:27 AM, xxxxx@gmail.com wrote:
>
>> The apps do not map that buffer.
>
> By “mapping” I meant that they access it, so they need to map (not sure that that’s the correct word) the buffer onto their virtual memory. While the mapping object is owned by the Audio Engine process, an app that accesses the microphone needs some kind of handle to it to call MapViewOfFile. So perhaps there’s a way to prevent from selected apps to gain that handle.

Audio apps do not use MapViewOfFile. Even the Audio Engine does not use MapViewOfFile. The Audio Engine sends a property request to the port driver, which calls the miniport, which will do the mapping in kernel mode and returns a process virtual address.

> By debugging audiodg.exe I see that it calls DuplicateHandle. Can I intercept NtDuplicateObject calls in a kernel driver, and disallow undesired calls? (I’m new to kernel development)

Which handle are they duplicating? These are kernel streaming drivers. They open a number of file handles, including one for the filter, one for each pin, one for the topology, etc, but all of those handles communicate using Kernel Streaming ioctls. I don’t know what you’d gain by duplicating the handles.

> Also, how protected is the audiodg.exe process? I’m able to attach a debugger to it, which means that a malware can gain access to it too. I guess that a malware can as well communicate directly with the audio drivers, as audiodg.exe does. So for a proper security solution, I might add protection to audiodg.exe and the audio driver.

You should not have been able to attach to the process unless you disabled its protected status, by setting DisableProtectedAudioDG to 1 inside of HKLM\Software\Microsoft\Windows\CurrentVersion\Audio.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I was mistaken about DuplicateHandle, it’s not really related. I thought about controlling communication of processes with audiodg.exe (I saw that audio processes use NdrClientCall4), but then if I deny it, I also deny audio output, which is undesirable.

which will do the mapping in kernel mode and returns a process virtual address.

I understand. Is it being done for every requesting process? Can I perhaps hook this, and deny the mapping for selected processes?

>If you don’t want to be recorded by the PC just don’t plug in the microphone.

Have you ever owned a laptop?

xxxxx@gmail.com wrote:

> which will do the mapping in kernel mode and returns a process virtual address.
I understand. Is it being done for every requesting process? Can I perhaps hook this, and deny the mapping for selected processes?

No.  Apparently, I have failed in several attempts to describe the
process; I will try again.

The Audio Engine is the ONLY PROCESS in the system that communicates
with audio drivers.  The WaveRT circular buffer is mapped only once, and
ONLY into the Audio Engine.  Real-time manipulation of the buffer,
therefore, happens ONLY in the Audio Engine.  Data transfers to and from
client apps are done by user-mode inter-process communication.

    app 1           app 2           app 3
      |               |               |
      |               |               |
      ±--------±----±--------------+
                |
               IPC
                |
              Audio
              Engine
                |
   user         |
   - - - - - - -|- - - - - - - - - - - -
   kernel       |
                |
      ±--------±--------+
      |         |         |
    audio     audio     audio
   driver 1  driver 2  driver 3


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

On Mon, Jun 18, 2018 at 10:12 AM, xxxxx@broadcom.com
wrote:
>>If you don’t want to be recorded by the PC just don’t plug in the microphone.
>
> Have you ever owned a laptop?
>

Until manufacturers start providing hardware switches the solution is
to open the laptop up and install one yourself or just permanently cut
the power traces.

In secure locations a laptop’s external ports are often filled with
epoxy. Microphones and cameras are removed entirely unless they are
needed.

For US readers, note that under the Magnuson-Moss warranty act a
manufacturer can’t deny you warranty coverage for opening your device
or performing repairs yourself. Obviously you would not be able to get
them to replace the microphone, but doing a modification like this
won’t let them avoid fixing any other problems.

Also note the statute of limitations on implied warranties (i.e.
merchantability and suitability for a particular purpose) under US
federal law is 4 years. Regardless of what a manufacturer says there
is thus an implied 4 year warranty.

Cheers,
R0b0t1

Thank you Tim. After several failed attempts, I’m taking a look at APOs. You wrote:

APOs are installed via the INF for hardware,
and are associated with a single piece of
hardware. You can’t add them globally.

I found an example of Microsoft, SwapAPO, which is supposed to swap the speakers’ left and right channel. As far as I understand, it should work globally, but I wasn’t able to make it work. Do you think that I can implement an “Endpoint effect” for a microphone, which will mute the output when I choose to?