Search code examples
winapietw

How to find the caller of Kernel32.Beep function with ETW traces?


We have a system where some malicious code sends out arbitrary beeps, probably by calling the Beep() function in the Win32 API

I need to find out which executable does this, and want to use ETW for that. Up to now, I could find out that the actual beeping is executed by a windows taskhostw.exe, which gives me no clue which app originally started the beeping.

Is there any way to find out who called Beep() in the first place? This is on a customer system, so any interactions with the UI are forbidden, it has to be some background trace gathering...

I'm using an extremely small test program TestBeep.exe for the tests, and I want to see in my ETW data that TestBeep.exe started the beeping...

#include <iostream>
#include <windows.h>
#include <utilapiset.h>

int main()
{
    std::cout << "Beeping now...\n";
    Beep(440, 1000);
    std::cout << "done.\n";
    return 0;
}

Solution

  • You can check who opens the Beep Device (\Device\Beep) which is a file. You can enable Handle Tracing and potentially filter by Handle type. But you should get pretty far by enabling handle tracing without any stacks to find who opens the Beep device. My newest version of ETWController can also filter by Handle type: https://github.com/Alois-xx/etwcontroller/releases/tag/2.5.2 which is a unique feature.

    enter image description here

    These settings should work inside ETWController:

    enter image description here

    If you cannot filter by handle type you should remove the stack walk events to get at least an idea when and which process did call beep. By adding some CPU sampling later you should be able to tell what this process was doing at that point in time.

    Update 1

    For starters I would just enable the Handle keyword and hope that it records long enough. Without Handle filters it is more tricky. Since it is a customer issue you could sample each day during working hours for one specific hour and collect that data each day until you find at least which process did it then it should be easier to find out who was doing this.

        <SystemProvider Id="SystemProvider_Handle" Base="SystemProvider_Monitoring">
                <Keywords Operation="Add">
                    <Keyword Value="Handle"/>
                </Keywords>
                <Stacks>
    <!--
                    <Stack Value="HandleCreate"/>
                    <Stack Value="HandleClose"/>
                    <Stack Value="HandleDuplicate"/>
    -->
                </Stacks>
            </SystemProvider>