Friday, September 25, 2009

Use cdb to see what files your application is opening.

In this post I'll show you how to use CDB to intercept CreateFile and see what files your application is opening. For this problem, Process Monitor is often a better tool, but the techniques I demonstrate work for any API you should learn them. This won't take much time, so if you've never done this before I recommend you follow along. First Load CDB against cmd:
 

    C:\Program Files\Debugging Tools for Windows (x64)>cdb.exe cmd.exe

    Microsoft (R) Windows Debugger Version 6.12.0000.526 AMD64
    Copyright (c) Microsoft Corporation. All rights reserved.

    CommandLine: cmd.exe
    Symbol search path is: *** Invalid ***
    ****************************************************************************
    * Symbol loading may be unreliable without a symbol search path.           *
    * Use .symfix to have the debugger choose a symbol path.                   *
    * After setting your symbol path, use .reload to refresh symbol locations. *
    ****************************************************************************
    Executable search path is:
    ModLoad: 00000000`49fc0000 00000000`4a018000   cmd.exe
    ModLoad: 00000000`77c10000 00000000`77db8000   ntdll.dll
    ModLoad: 00000000`779f0000 00000000`77b0e000   C:\Windows\system32\kernel32.dll
    ModLoad: 000007fe`fde90000 000007fe`fdef9000   C:\Windows\system32\KERNELBASE.dll
    ModLoad: 000007fe`febd0000 000007fe`fec6f000   C:\Windows\system32\msvcrt.dll
    ModLoad: 000007fe`fc850000 000007fe`fc858000   C:\Windows\system32\WINBRAND.dll
    ModLoad: 00000000`77b10000 00000000`77c0b000   C:\Windows\system32\USER32.dll
    ModLoad: 000007fe`fee70000 000007fe`feed7000   C:\Windows\system32\GDI32.dll
    ModLoad: 000007fe`febc0000 000007fe`febce000   C:\Windows\system32\LPK.dll
    ModLoad: 000007fe`fe2b0000 000007fe`fe37a000   C:\Windows\system32\USP10.dll
    (1268.1dfc): Break instruction exception - code 80000003 (first chance)
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll -
    ntdll!CsrSetPriorityClass+0x40:
    00000000`77cbb790 cc              int     3
    0:000> g
    ModLoad: 000007fe`fe640000 000007fe`fe66e000   C:\Windows\system32\IMM32.DLL
    ModLoad: 000007fe`fe530000 000007fe`fe639000   C:\Windows\system32\MSCTF.dll
    Microsoft Windows [Version 6.1.7110]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

    C:\Program Files\Debugging Tools for Windows (x64)>
    (1268.1c1c): Control-C exception - code 40010005 (first chance)
    First chance exceptions are reported before any exception handling.
Next find something like CreateFile to breakpoint:
 
    0:001> x *!*CreateFile*
    00000000`779fd6a0 kernel32!CreateFileMappingA ()
    00000000`779ffb30 kernel32!CreateFileMappingW ()
    00000000`77a02740 kernel32!CreateFileW ()
    00000000`77a124b0 kernel32!CreateFileA ()
    00000000`77a3b980 kernel32!CreateFileMappingNumaW ()
    00000000`77a54d50 kernel32!CreateFileMappingNumaA ()
    00000000`77a63740 kernel32!LZCreateFileW ()
    00000000`77a66450 kernel32!CreateFileTransactedW ()
    00000000`77a665f0 kernel32!CreateFileTransactedA ()
    00000000`77c5ea20 ntdll!NtCreateFile ()
    00000000`77c5ea20 ntdll!ZwCreateFile ()
    000007fe`fde94990 KERNELBASE!CreateFileW ()
    000007fe`fde96270 KERNELBASE!CreateFileMappingNumaW ()
    000007fe`fdea3120 KERNELBASE!CreateFileMappingW ()
    000007fe`fdec9cc0 KERNELBASE!CreateFileA ()
Set the breakpoint on Kernel32!CreateFileW (You can figure that out by looking on MSDN)
 
    0:001> bm kernel32!CreateFileW
    breakpoint 1 redefined
      1: 00000000`77a02740 @!"kernel32!CreateFileW"
Lets open a file and make sure our function is called!
 
    0:002> g

    C:\Program Files\Debugging Tools for Windows (x64)>type c:\foo.txt
    Breakpoint 1 hit
    kernel32!CreateFileW:
    00000000`77a02740 48895c2408      mov     qword ptr [rsp+8],rbx ss:00000000`0024e180=000000000031df00
    0:000>

Our breakpoint is hit. Lets figure out the filename being opened. To do this, we lookup the parameter list of CreateFile on MSDN. Filename is the first parameter. Next we look up the calling convention. On AMD64, the first paramater lives in rcx. Lets dump rcx as a unicode string:
 
    0:000> du rcx
    00000000`0031a310  "c:\foo.txt"
    0:000>
Awesome - it worked. Lets make our breakpoint automatically print, and continue execution so it's non-intrusive.
 
    0:000> bm kernel32!CreateFileW "du @rcx;g"
    breakpoint 1 redefined
      1: 00000000`77a02740 @!"kernel32!CreateFileW"
    0:000> g

    C:\Program Files\Debugging Tools for Windows (x64)>type c:\fo2.txt
    00000000`0031a310  "c:\fo2.txt"
    The system cannot find the file specified.

    C:\Program Files\Debugging Tools for Windows (x64)>type c:\IgorOpenedThisFile.txt
    00000000`0031b9e0  "c:\IgorOpenedThisFile.txt"
    The system cannot find the file specified.

    C:\Program Files\Debugging Tools for Windows (x64)>
Notice the debugger spew intersperesed with cmd output. Anytime we open a file we'll see it in the spew! Use this approach to debug all sorts of I wonder what's going on problems.

No comments: