Debugging without source code and without symbols is hard. The approach to be taken varies much with what you can observe and what assumptions you can make. The following sounds reasonable for your situation.
Diff the 64 bit file accesses against 32 bit version
Since the 64 bit version works, see what the difference in file accesses is. You can export Process Monitor logs to CSV and write a tool which analyzes the file accesses. Your analysis tool should probably
- summarize multiple file read accesses with different offsets to a single file access for the whole file.
- ignore the read order, because the order seems less important.
- ignore DLLs at first
Maybe you can even do that in Excel itself.
Capturing file access calls
First of all I think using Process Monitor is already a good approach. You find out what the application is doing without knowing anything about it, so that would be my first choice.
Of course it's hard to narrow down the list of files in question. If necessary you need to go through all of them, e.g. with the help of a batch file and find a command line tool which can help finding the application which has opened the file. In this case, look at SysInternals Handle. It is a command line utility and you can give it a file name. Basically, it's the command line version of Process Explorer (see below).
Reading files and writing files is usually done through API calls, so API Monitor is another option. Filter for all file access methods which are suspect (ReadFile, ReadFileEx, LockFile, LockFileEx, WriteFile, WriteFileEx, ...).
This can also be achieved in WinDbg by setting breakpoints, but you might hit them very often, so handling them probably needs some automation. You can specify a command string for the bp
command.
Be lucky
It might happen that the file name which was intended to be used as argument for the %s
format string is somewhere in memory.
- Take a crash dump at the time the application shows the message
- Use the SysInternals Strings utility to dump all strings of the dump.
- Either filter that output directly for
C:\
, D:\
etc by piping it to the find
command or redirect it to a text file for later analysis
This will still leave you with a lot of files, so finding the culprit is not much easier than with the previous approach. Again, narrow the list down with other tools, e.g. handle
.
- Take a crash dump at the time the application shows the message
- Open the dump in WinDbg
- Dump strings for some of the addresses you find on the stack. Since file names in NTFS are Unicode,
du <address>
should work fine here.
This definitely needs more knowledge on internal stuff, e.g. where to find good pointers etc.
Analyzing First Chance Exceptions
If the application relies on exceptions, you might get some insight by checking for first chance exceptions. However, if the application does a good precondition check, there will be less exceptions, thus lowering your chances to grab something useful.
If the situation reproduces well, you can
- Set up WinDbg as the debugger for that process using Image File Execution Options.
- Open a logfile with
.logopen /t /u c:\firstchanceexceptions.log
- Let all exceptions be dumped using
sxe -c ".exr -1;k;g" *
. The g
in that command will immediately continue so that the application does (hopefully) not run into timeouts.
- Continue execution with
g
- When the application terminates, close the logfile with
.logclose
- Review the log file for interesting exceptions / interesting call stacks
- Reproduce the error but stop on interesting exceptions this time
- Look at method parameters and memory whether you find the file name (again, use
du <address>
)
Finding the application which belongs to a message box
If you can't figure out which application shows the error message, e.g. because of a bad message title, do this:
Download SysInternals Process Explorer and run it.
Drag the cross hair from the toolbar over the window.
Process Explorer now highlights the executable which owns the window
Finding the locking application if the file name is printed
If the dialog shows the file name and not just "%s":
Also use Process Explorer
Use Find/Find handle or DLL or press Ctrl+F
Type the file name or parts of the file name