Search code examples
windowsdebuggingwindbgwfp

What are options for debugging WFP callout driver


I am new to kernel mode windows driver development and having issues getting debug information out of the WFP callout samples. I am looking for either more options or tips of what I am doing wrong with the options I have been trying.

To start with I downloaded the WFP sampler and followed the instructions in it's description. I am using a Windows 8.1 x64 host and a Windows 7 x64 target connected via a simulated serial cable. They are both VirtualBox VMs.

The primary command I am debugging with is

WFPSampler.Exe -s PROXY -l FWPM_LAYER_ALE_BIND_REDIRECT_V4 -aaid "C:\Program Files (x86)\Internet Explorer\iexplore.exe" -pla 10.0.2.15 -v

Where 10.0.2.15 is the IP address of a diffrent network interface than the routing table is endign traffic to. I also used the following inspect command as recommended by the instructions:

WFPSampler.exe -s BASIC_PACKET_EXAMINATION -l FWPM_LAYER_INBOUND_IPPACKET_V4 -v

"netsh wfp show state" shows the callout and filter associated with the expected layer

However I never got any messages from traceview as per the last steps of those instructions. Tracelog had similar lack of output. This was true with or without WPP tracing enabled on the driver project. I also tried higher verbosity, all to no effect.

Additionally the remote debugger in visual studio either stopped at "Driver Post Install Actions (x64) (possible reboot): Pass" or "Waiting to reconnect..." rebooting the target did not cause more output in the Debugger Immediate Window (the Output window never got any output). Rebooting the target VM did not get any unusual prompts (some things I read implied it should). The reconnect checkbox when setting up the debugger sometimes caused it to get past the "Waiting to reconnect..." prompt, other times it was not needed. I set a number of breakpoints that should have been hit including one at the top of every classify function and none were ever hit.

I tried to debug with WinDbg, but well, frankly I can't find the documentation about how to use this tool. I start it on the target machine and chose kernel debug, local. then I get a prompt that tells me the symbol search path is invalid and no clue what I am supposed to set it to. Any documentation on how to use this tool as opposed to just installing it may be helpful if it lets me debug these callout drivers.

Finally of course I tried just debugging it based on symptoms and I find that the examination callout does nothing as far as I can tell, while the proxy callout just eats all traffic from the targeted application, with one caveat. That caveat is that when I target firefox or chrome with the proxy callout and try to launch that app it fails to launch a UI and the partially started process cannot be killed from task manager.

I assumed that behavior may be the result of the sample failing to check FwpsQueryPacketInjectionState but modifying as best I can figure out that should be used does not seem to change the behavior.

So in short I am stuck and need direction please?


Solution

  • I started experimenting with the WFPSampler and also discovered that tracing didn't work. Oddly enough, there was a lot of additional code to make WPP tracing work on multiple OS's, but the sample doesn’t capture any trace events. So I debugged it and found the call to the nt!WmiTraceMessage always passed 2 as the TRACE_HANDLE. This seemed bad. Safe it to say, this wasn't exactly straight forward to unscramble WPP macros and then finally find the origin in the .vcxprog file. The definition of WPP_COMPID_LEVEL_LOGGER(COMPID,LEVEL)=2 is incorrect. While I was there, I also converted the DbgPrintEx Levels to match Tace_Level by adding 2 so Error/Warning match the model.

    Complete the following steps for SysLib/WFPSampler and Sys/WFPSamplerCalloutDriver

    1. Open the Project
    2. Right Click on WFPSamplerCalloutDriver
    3. Unload Project
    4. Right Cick on WFPSamplerCalloutDriver
    5. Edit WFPSamplerCalloutDriver.vcxproj
    6. Type: WppPreprpocessorDefinitions

    7. Change this definition in both places in the file:

    To:

    <WppTraceFunction>DbgPrintEx(COMPID,LEVEL,MSG,...)</WppTraceFunction
    <WppPreprocessorDefinitions>WPP_COMPID_LEVEL_LOGGER(COMPID,lvl)=(WPP_CONTROL(0).Logger),;WPP_COMPID_LEVEL_ENABLED(COMPID,lvl)=(WPP_CONTROL(0).Level >= lvl+2)</WppPreprocessorDefinitions>
    
    1. Save the File
    2. Right Cick on WFPSamplerCalloutDriver
    3. Click Reload Project
    4. Rebuild

    I believe if you adopt this model of using DbgPrintEx as your trace function, you can switch to WPP without editing the entire project. However, I still think it's better to just convert in your program.

    Cheers,

    John