Solving .net source code lines problem in windbg with SOSEX

Posted in: , , by . No comments

 
Introduction

The SOSEX debugger extension has all kinds of commands that work with source code lines, for example !mk displays a stack trace with both managed and unmanged frames, potentially mapping managed frames to their source code locations.

Like native source code lines support, it requires the symbols file (PDB) to be available to the debugger. Unfortunately, .NET doesn’t call LoadLibrary on its managed non mixed-mode assemblies. Not calling LoadLibrary causes the debugger to not see the module (assembly, DLL, I have used those terms interchangeably in this post), thus obviously unable to load its symbols. That happens because the debugger gets the list of modules from the ntdll loader’s list, which is populated by LoadLibrary calls.

CoreCLR does call LoadLibrary. I’m guessing that not calling is a compatibility issue rather than security issue, as CoreCLR calls LoadLibrary with the DONT_RESOLVE_DLL_REFERENCES flag, which prevents native code from running (DLLMain isn’t called) in an untrusted assembly.

If the assembly is loaded after we have attached, the debugger actually sees it, because after attaching it receives lower level notifications of module loading, at the file mapping level (Managed DLLs are still mapped to the process). You can list the loaded modules with the lm command.

So this problem is only relevant to assemblies that were loaded before attaching the debugger.

Solution

Despite its name, Process Explorer’s DLLs pane isn’t limited to DLLs loaded by LoadLibrary, but it actually displays all memory mapped files, including all managed DLLs.

For example, some managed application:

image_thumb1

Luckily, there’s a way of “hinting” the debugger where a DLL is located in the target’s memory space with the .reload command, for our case we could run:

.reload /f ClassLibrary1.dll=0x2700000

Notice that I took the base address from the above Process Explorer’s screenshot. /f simply forces immediate symbols load. After that, all the commands that support sources (like !mk) would work on code from that DLL with source lines.

The option of specifying base address is usually used for kernel debugging, in cases where some of the memory that contains the loaded DLLs is paged out, so the debugger can’t figure out what is loaded by itself.

Posted in: , , by . No comments

The permalink

Leave a Reply