Debugging Third-Party Applications – Part 1
12 January 2012, by Rupert Wood
This is a short series of posts as a worked-example of how to debug into someone else’s code. It covers a problem I ran into with Microsoft Exchange’s Outlook Web Access (OWA), which Microsoft has since fixed, but the advice is intended to apply to many other situations.
One of the systems we have at Softwire is Exchange’s Outlook Web Access (OWA). Whilst I’m working on a customer site I use OWA to read my emails from the office and also read a few blogs through Outlook’s RSS feed support. However this suddenly stopped working for one of the Microsoft blogs I read:
I tried searching the web for this error message but only found a few other people with the same problem and no relevant solution. So I set about debugging this myself!
Where to start? The first step is to track down the code that’s involved. I logged into our Exchange server and had a look around: there are directories called ClientAccess and OWA so this was easy to find. I now had:
- a bin directory containing five DLLs (plus their internationalized language resources)
From a user’s perspective it isn’t easy to spot whether or not the URL block is performed on the server side or the client side, i.e. whether the code responsible will be in that bin directory or amongst those scripts. To make matters worse, the scripts have been ‘minified’ – reduced down to a simplified form that will download faster and run identically but that is much harder for humans to read.
From those files, a sensible (and quick!) next step is to dig through the files we have to find the error message displayed. In most applications these will be stored in a language-specific resource file, perhaps with some components of the string substituted in and perhaps as several constituent parts assembled into one string for display. You should:
- file-search through all of the files for the error message string
- search again as a Unicode (UTF-16) search: Windows uses 16-bit string characters internally for internationalisation, and DLL resource segments are stored in this format
- if no hits so far, search for short segments of the string to try and find a partial match or a string template match.
This often isn’t a lot of help in itself: if the string appears in a resource segment somewhere then the application will reference the resource string by ID. That ID will be near-impossible to track down amongst a large volume of binary code where there will be many false positive matches, and identifying the correct one can involve digging around surrounding code and calls for the string resource load, or debugging and setting breakpoints in the right system calls. Without further help, this initial string search is likely only good for a confirmation that you’re actually looking in the right place.
Thankfully this wasn’t a problem for my bug: when you mouse-over a blocked link in OWA you’ll see a reference to UrlBlockedError.aspx, the page that hosts the internationalized “This link has been disabled” message. This exists as a file UrlBlockedError.aspx in the OWA directory.
So I could then instead chase down the code that was redirecting me to UrlBlockedError.aspx. In the next part I’ll cover investigating that code, which – fortunately for me – turned out to be .NET code.