DotNet Debugging
Post

DotNet Debugging

Manipulation of Assembly Attributes for Debugging

Debugging .NET web applications can sometimes be a bit tricky due to the optimizations that are applied to the executables at runtime. One of the ways these optimizations manifest themselves in a debugging session is by preventing us from setting breakpoints at arbitrary code lines. In other words, the debugger is unable to bind the breakpoints to the exact lines of code we would like to break at. As a consequence of this, in addition to not being able to break where we want, at times we are also not able to view the values of local variables that exist at that point. This can make debugging .NET applications harder than we would like.

Fortunately, there is a way to modify how a target executable is optimized at runtime. More specifically, most software will be compiled and released in the Release version, rather than Debug. As a consequence, one of the assembly attributes would look like this:

1
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

In order to enable a better debugging experience, i.e. to reduce the amount of optimization performed at runtime, we can change that attribute to resemble the following:

1
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

As it so happens, this can be accomplished trivially using dnSpy. However, we need to make sure that we modify the correct assembly before we start debugging. In this instance, our target is the C:\inetpub\wwwroot\dotnetnuke\bin\DotNetNuke.dll file. It is important to note that once the IIS worker process starts, it will NOT load the assemblies from this directory. Rather it will make copies of all the required files for DNN to function and will load them from the following directory: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\dotnetnuke\.

As always, before we do anything we should make a backup of the file(s) we intend to manipulate. We can then open the target assembly in dnSpy, right-click on its name in the Assembly Explorer and select the Edit Assembly Attributes (C#) option from the context menu (Figure 10). The same option can also be accessed through the Edit menu.

Figure 10: Accessing the Edit Assembly Attributes menu Figure 10: Accessing the Edit Assembly Attributes menu Clicking on that option opens an editor for the assembly attributes.

Here we need to replace the attribute we mentioned in Listing 16 (line 11) to the contents found in Listing 17.

Once we replace the relevant assembly attribute, we can just click on the Compile button, which will close the edit window. Finally, we’ll save our edited assembly by clicking on the File > Save Module menu option, which presents us with the following dialog box:

We can accept the defaults and have the edited assembly overwrite the original. At this point we are ready to start using our dnSpy debugger.

FileSystemUtils

According to the original advisory, the DotNetNuke.dll assembly contains a class called FileSystemUtils. Furthermore, this class implements a method called PullFile. If we use the dnSpy search function, we can easily locate this function and look at its implementation.